如何在Python中使用线程正确执行非阻塞任务

时间:2013-12-24 12:41:18

标签: python multithreading python-2.7 concurrency python-multithreading

我编写了一个小的python类,它扩展了'threading.Thread'并使用SMTP_SSL模块向我自己发送一封自动电子邮件。然而,在我的调用python文件中,似乎事情更顺序地发生:

import sysErrorMail
import logging

logging.basicConfig(level=logging.DEBUG,
                format='[%(levelname)s] (%(threadName)-10s) %(message)s',
                )

returnValue = -1
myMailInstance = sysErrorMail.sysMail()
logging.debug('Starting the mail thread')

returnValue = myMailInstance.run()

logging.debug('This message should be printed before the mail thread ends')

if returnValue == 0:
    logging.debug('Success')
elif returnValue == 1:
    logging.debug('Failed')

输出是:

[DEBUG] (MainThread) Starting the mail thread
[DEBUG] (Worker    ) Mail thread reports that the mail was sent successfully
[DEBUG] (MainThread) This message should be printed before the mail thread exits
[DEBUG] (MainThread) Success

似乎logging.debug('This message should be printed before the mail thread ends')等待我的其他线程结束,然后才打印它的消息。为什么会发生这种情况,我应该怎么做呢?

编辑:好吧,如果我替换

returnValue = myMailInstance.run()

使用:

returnValue = myMailInstance.start()

工作正常,但它现在在returnValue上没有打印...

2 个答案:

答案 0 :(得分:1)

正如bakuriu所写,start()是运行线程的正确方法。但它没有返回值,因为它是未知的,线程可以运行一段时间来获得结果。所以你应该用其他方式获得返回值。这应该对你有所帮助:

how to get the return value from a thread in python?

答案 1 :(得分:1)

您需要做一些事情才能让您的代码按预期运行。

首先:向您的线程实例添加一个属性result和一些访问方法。

import threading
class YourThread(threading.Thread):
    ...                # code you already have.
    self.__result      # code I'm suggesting.

    def get_result(self):
        return self.__result

    def run(self):
        # You have to modify the code in your run method in order to provide
        # a value for self.__result.

第二:主线程必须wait myMailInstance结束,然后询问结果。因此,您需要在线程上调用join

myMailInstance.start()

logging.debug('This message should be printed before the mail thread ends')

myMailInstance.join()

if myMailInstance.get_result() == 0:
    logging.debug('Success')
elif myMailInstance.get_result() == 1:
    logging.debug('Failed')

就是这样。