如果我理解正确,您想在一个单独的线程中运行一个函数吗?有几种方法可以做到这一点。但基本上,您可以像下面这样包装函数:
class MyClass: somevar = 'someval' def _func_to_be_threaded(self): # main body def func_to_be_threaded(self): threading.Thread(target=self._func_to_be_threaded).start()
可以使用装饰器将其缩短:
def threaded(fn): def wrapper(*args, **kwargs): threading.Thread(target=fn, args=args, kwargs=kwargs).start() return wrapperclass MyClass: somevar = 'someval' @threaded def func_to_be_threaded(self): # main body
编辑 带有手柄的更新版本:
def threaded(fn): def wrapper(*args, **kwargs): thread = threading.Thread(target=fn, args=args, kwargs=kwargs) thread.start() return thread return wrapperclass MyClass: somevar = 'someval' @threaded def func_to_be_threaded(self): print 'xyz'
可以如下使用:
>>> my_obj = MyClass()>>> handle = my_obj.func_to_be_threaded()>>> handle.join()
现在,如果您希望从函数中返回值,则可以进一步扩展它。考虑一下:
from threading import Threadfrom concurrent.futures import Futuredef call_with_future(fn, future, args, kwargs): try: result = fn(*args, **kwargs) future.set_result(result) except Exception as exc: future.set_exception(exc)def threaded(fn): def wrapper(*args, **kwargs): future = Future() Thread(target=call_with_future, args=(fn, future, args, kwargs)).start() return future return wrapperclass MyClass: @threaded def get_my_value(self): return 1>>> my_obj = MyClass()>>> fut = my_obj.get_my_value() # this will run in a separate thread>>> fut.result() # will block until result is computed1
如果您没有并发.futures.Future类(例如,因为您使用的是Python2.7或更早版本),则可以使用以下简化的实现:
from threading import Eventclass Future(object): def __init__(self): self._ev = Event() def set_result(self, result): self._result = result self._ev.set() def set_exception(self, exc): self._exc = exc self._ev.set() def result(self): self._ev.wait() if hasattr(self, '_exc'): raise self._exc return self._result
我建议您阅读并发模块模块,因为它有很多简洁的工具。例如,
Thread应将类替换为
ThreadPoolExecutor实例以限制并发性(例如,您不想向10k线程发送垃圾邮件)。同样,
ThreadPoolExecutor使用代码甚至更简单(并且更不容易出错):
from concurrent.futures import ThreadPoolExecutortp = ThreadPoolExecutor(10) # max 10 threadsdef threaded(fn): def wrapper(*args, **kwargs): return tp.submit(fn, *args, **kwargs) # returns Future object return wrapper
请记住,
tp.shutdown()完成所有并行工作之后,您必须要做的事情。



