我最近开始使用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
如果您没有并发.futures.Future类(例如,因为您使用的是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
我建议您阅读并发模块模块,因为它有很多简洁的工具。例如,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()
完成所有并行工作之后,您必须要做的事情。
我创建了3个线程,它们正在访问外部类的内部类。 在输出中,我可以看到类中的静态变量没有按顺序更新。 如果有人能解释在多线程情况下如何处理内部类,将会有很大帮助?我们能同步整个内部类吗? 事先谢谢你的帮助。
我很难理解内部类线程的行为。 它总是打印出“main”,并且线程是按顺序执行的。为什么内部类线程的执行由主线程执行? 谢谢!
问题内容: 我想知道Python内置容器(列表,向量,集合…)是否是线程安全的?还是我需要为共享变量实现锁定/解锁环境? 问题答案: 您需要为将在Python中修改的所有共享变量实现自己的锁定。你不必担心从不会被修改的变量读(即并发读取都OK了),所以稳定的类型(,,)都 可能是 安全的,但它不会伤害。对于你将要改变的东西- ,,,和大多数其他的对象,你应该有自己的锁定机制(而就地操作都OK在大多
问题内容: 我正在努力加快某些过程的执行速度,这些过程将大量记录(大多数是几百万个)发布到Elasticsearch。在我的C#代码中,我已经使用Dataflow实现了一个多线程解决方案,如下所示: 然后我要实现的发送批量请求调用: 我的问题 ,你 是对的实用性存在的数据流管道的一部分的锁内执行额外的线程。 这个可以吗?我可以在性能,执行,缓存/内存丢失等方面看到任何潜在的问题吗? 任何见识都会很
我试图了解python类是如何实现的,以及分配给它们会消耗多少内存。所以我创建了一个大的numpy数组,然后将其分配给一个类,然后将该类分配给另一个类(如下所示)。 使用sys。getsizeof似乎无助于获取numpy阵列的内存大小。Numpy数组使用nbytes,但是引用Numpy数组的类没有nbytes作为方法。 如果我更改了,则和会自动更新以反映它。Python文档说明对象别名类似于指针。
问题内容: Python的内部/嵌套类使我感到困惑。没有他们,有什么事情是无法完成的吗?如果是这样,那是什么东西? 问题答案: 引用自http://www.geekinterview.com/question_details/64739: 内部类的优点: 类的逻辑分组 :如果一个类仅对另一个类有用,那么将其嵌入该类并将两者保持在一起是合乎逻辑的。嵌套此类“帮助程序类”可使它们的程序包更加简化。 增