gpt4 book ai didi

类中的 Python 线程

转载 作者:IT老高 更新时间:2023-10-28 21:52:56 31 4
gpt4 key购买 nike

我最近开始使用 python 的线程模块。经过一些试验和错误后,我设法使用大多数教程中给出的以下示例代码使基本线程工作。

class SomeThread(threading.Thread):
def __init__(self, count):
threading.Thread.__init__(self)

def run(self):
print "Do something"

我的问题是:我有一个包含类变量的类和一个我想在单独的线程中运行的函数。然而,该函数使用类变量并且还写入类变量。像这样:

class MyClass:
somevar = 'someval'

def func_to_be_threaded(self):
# Uses other class functions
# Do something with class variables

那么我将如何本质上“将线程类放入 MyClass”。这样如果 MyClass().func_to_threaded() 被调用,它将在一个线程中运行。

最佳答案

如果我理解正确,您想在单独的线程中运行一个函数吗?有几种方法可以做到这一点。但基本上你像这样包装你的函数:

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 wrapper

class 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 wrapper

class 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 Thread
from concurrent.futures import Future

def 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 wrapper


class 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 computed
1

如果您没有 concurrent.futures.Future class (因为例如您使用的是 Python2.7 或更早版本)那么您可以使用这个简化的实现:

from threading import Event

class 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

我建议通读 concurrent.futures模块,因为它有很多简洁的工具。例如,应该将 Thread 类替换为 ThreadPoolExecutor 实例以限制并发性(例如,您不想发送 10k 线程垃圾邮件)。此外,使用 ThreadPoolExecutor 代码更简单(更不容易出错):

from concurrent.futures import ThreadPoolExecutor

tp = ThreadPoolExecutor(10) # max 10 threads

def threaded(fn):
def wrapper(*args, **kwargs):
return tp.submit(fn, *args, **kwargs) # returns Future object
return wrapper

请记住,您必须在完成所有并行工作后tp.shutdown()

关于类中的 Python 线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19846332/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com