1. 程式人生 > 實用技巧 >Python 多執行緒控制檯輸出錯亂

Python 多執行緒控制檯輸出錯亂

背景

多執行緒在使用 print() 時,會在控制檯上出現形如以下的錯亂顯示:

簡單搜尋了一下,網上有說 python3 的 print 是執行緒安全的,但是我這個是 python 3.8.5 啊。。

解決方法

再仔細看一下,發現只有換行是錯亂的。這裡我想到了 print() 是自動新增換行的,可能這個新增換行的時候不是執行緒安全的,於是測試一下,自己新增換行:

print(f'[{threading.current_thread().getName()}]{proxy_ip}-連線失敗:連線超時\n', end='')

結果就正常顯示了!。。

更簡便的方法

  1. 不想每次都設定 end的話,可以使用 Python 的偏函式:
import functools
print = functools.partial(print, end='')

但是這樣的話,還需要你自己在每次行末尾新增換行符。

  1. 還可以再自己直接重新定義一下 print() 函式解決上面的問題:
# 原先的print函式
_print = print


# 定義新的print函式
def print(text):
    '''
    使輸出有序進行,不出現多執行緒同一時間輸出導致錯亂的問題。
    '''
    _print(text + '\n', end='')
  • 這裡只能列印字串,如果還需其他輸出需求需要自行修改。
  1. print()
    加鎖的解決方法:
# 原先的print函式和主執行緒的鎖
_print = print
mutex = threading.Lock()


# 定義新的print函式
def print(text, *args, **kw):
    '''
    使輸出有序進行,不出現多執行緒同一時間輸出導致錯亂的問題。
    '''
    with mutex:
        _print(text, *args, **kw)
  • 也可以作為每個執行緒類的方法,把建立鎖放在 __init()__ 裡,確保所有執行緒的鎖都是主執行緒的。