背景
多線程在使用 print()
時,會在控制台上出現形如以下的錯亂顯示:
簡單搜索了一下,網上有說 python3 的 print
是線程安全的,但是我這個是 python 3.8.5 啊。。
解決方法
再仔細看一下,發現只有換行是錯亂的。這里我想到了 print()
是自動添加換行的,可能這個添加換行的時候不是線程安全的,於是測試一下,自己添加換行:
print(f'[{threading.current_thread().getName()}]{proxy_ip}-連接失敗:連接超時\n', end='')
結果就正常顯示了!。。
更簡便的方法
- 不想每次都設置
end
的話,可以使用 Python 的偏函數:
import functools
print = functools.partial(print, end='')
但是這樣的話,還需要你自己在每次行末尾添加換行符。
- 還可以再自己直接重新定義一下
print()
函數解決上面的問題:
# 原先的print函數
_print = print
# 定義新的print函數
def print(text):
'''
使輸出有序進行,不出現多線程同一時間輸出導致錯亂的問題。
'''
_print(text + '\n', end='')
- 這里只能打印字符串,如果還需其他輸出需求需要自行修改。
- 對
print()
加鎖的解決方法:
# 原先的print函數和主線程的鎖
_print = print
mutex = threading.Lock()
# 定義新的print函數
def print(text, *args, **kw):
'''
使輸出有序進行,不出現多線程同一時間輸出導致錯亂的問題。
'''
with mutex:
_print(text, *args, **kw)
- 也可以作為每個線程類的方法,把創建鎖放在
__init()__
里,確保所有線程的鎖都是主線程的。