簡體   English   中英

Python 如何實現我的 Email Class 的線程化

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM