[英]Python How to Implement Threading of my Email Class
我有一個相當大的 email class 構造和發送各種帶有 mime、附件等的電子郵件。
一切正常,但它是從我的主循環調用的,使用 smtplib 的 sendmail 方法有時會因為另一端的問題而阻塞幾秒鍾。
我想在一個新線程中運行代碼,以便我的主循環可以繼續運輸。
我嘗試了兩種方法都沒有成功:
使用線程調用我的 class
從 Thread 繼承我的 V1 class
也不停止阻塞。 下面是我的 class (V1) 和我嘗試過的工作骨架。 成功將是在“開始”之后立即看到“完成”,而不是等待 3 秒讓 sendmail 完成。 希望有一個簡單的方法來做到這一點......
from time import sleep
from threading import Thread
class EMailv1():
def __init__(self):
self._from_address = 'a@b.com'
self._to_addresslist = []
def buildmessage(self, **kwargs):
message ={}
return message
@staticmethod
def sendmail(message):
sleep(5)
return
class EMailv2(Thread):
def __init__(self):
Thread.__init__(self)
self._from_address = 'a@b.com'
self._to_addresslist = []
def run(self):
pass
def buildmessage(self, **kwargs):
message ={}
return message
@staticmethod
def sendmail( message):
sleep(3)
return
if __name__ == "__main__":
print('Starting V1 class send in current manner, which blocks if smtplib cannot deliver mail')
email =EMailv1()
msg = email.buildmessage(a='a',b='b')
email.sendmail(msg)
print('v1 Done after sendmail sleep finishes')
print('Starting threaded call to send V1 class')
email = EMailv1()
msg = email.buildmessage(a='a',b='b')
t = Thread(target=email.sendmail(msg))
t.start()
print('Threaded call of V1 Done after sendmail sleep finishes')
print('Starting V2 class inheriting Thread')
email = EMailv2()
msg = email.buildmessage(a='a',b='b')
email.start()
email.sendmail(msg)
print('V2 Done after sendmail sleep finishes')
在您的第二個版本中,而不是
t = Thread(target=email.sendmail(msg))
你應該做
t = Thread(target=email.sendmail, args=[msg])
以您編寫的方式,它在構建線程之前評估email.sendmail(msg)
,這就是為什么您看到在繼續之前等待 5 秒。
相反,您應該將目標 function 和它的 args 分別傳遞給線程,而不對其進行評估。
這是一個固定的最小化版本:
from time import sleep
from threading import Thread
class EMailv1():
def __init__(self):
self._from_address = 'a@b.com'
self._to_addresslist = []
def buildmessage(self, **kwargs):
message ={}
return message
@staticmethod
def sendmail(message):
sleep(5)
print("Launched thread: I'm done sleeping!")
return
if __name__ == "__main__":
print('Main thread: Starting threaded call to send V1 class')
email = EMailv1()
msg = email.buildmessage(a='a', b='b')
t = Thread(target=email.sendmail, args=[msg])
t.start()
print("Main thread: I have created the thread, and am done.")
Output:
Main thread: Starting threaded call to send V1 class
Main thread: I have created the thread, and am done.
Launched thread: I'm done sleeping!
話雖如此,我還建議您查看 Python 中提供的一些抽象,用於執行多線程工作。 例如,看看像ThreadPoolExecutor這樣的特性——這些通常比直接使用Thread
更可取。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.