在Python中创建线程
我有一系列的“任务”,想要在不同的线程中运行。这些任务是由不同的模块来完成的,每个模块都包含处理其任务的业务逻辑。
给定一组任务,我希望能够为每个模块启动一个新的线程,如下所示。
from foobar import alice, bob charles
data = getWorkData()
# these are enums (which I just found Python doesn't support natively) :(
tasks = (alice, bob, charles)
for task in tasks
# Ok, just found out Python doesn't have a switch - @#$%!
# yet another thing I'll need help with then ...
switch
case alice:
#spawn thread here - how ?
alice.spawnWorker(data)
显然,我还是在用C++的思维方式。请问我该如何用Python的方式,利用Python的“枚举”和“开关”,来在新线程中运行一个模块呢?
显然,这些模块都会有一个类,它是从一个叫做Plugin的抽象基类(ABC)派生出来的。spawnWorker()方法会在Plugin接口中声明,并在各个模块实现的类中定义。
也许,还有更好的(也就是更符合Python风格的)做法?我很想知道。
[编辑]
我刚刚多读了一些,似乎Python并没有真正意义上的线程实现(至少不是C++程序员所理解的那种)。不过,这对我来说并不是问题。每个任务都比较耗时,我不想等一个任务完成后再开始另一个,这就是我使用线程的原因。时间片调度对我来说没什么影响——只要它们几乎同时(或者紧接着)启动,Python就可以在这些线程之间随意进行时间片调度——这对我来说没问题。
我在这里看到过一个类似问题的回答。
有用户提供了一个简单的线程类,如下所示:
import threading
class Foo (threading.Thread):
def __init__(self,x):
self.__x = x
threading.Thread.__init__(self)
def run (self):
print str(self.__x)
for x in xrange(20):
Foo(x).start()
我在考虑将这个用于我的ABC Plugin。那么我的问题是,实际任务的代码应该放在哪里(也就是业务逻辑)?我假设这应该放在Foo类的run()方法中(这个问题很明显,我知道,但我不想做任何假设)。
我的想法是对的还是有问题(如果有问题,我错过了什么)?
4 个回答
顺序执行:
from foobar import alice, bob, charles
for fct in (alice, bob, charles):
fct()
并行执行:
from threading import Thread
from foobar import alice, bob, charles
for fct in (alice, bob, charles):
Thread(target=fct).start()
import threading
from foobar import alice, bob, charles
data = get_work_data() # names_in_pep8 are more Pythonic than camelCased
for mod in [alice, bob, charles]:
# mod is an object that represent a module
worker = getattr(mod, 'do_work')
# worker now is a reference to the function like alice.do_work
t = threading.Thread(target=worker, args=[data])
# uncomment following line if you don't want to block the program
# until thread finishes on termination
#t.daemon = True
t.start()
把你的逻辑放在对应模块的 do_work
函数里。
与其使用 switch-case 这种方式,不如用更合适的多态性来处理问题。比如,在 Python 中,你可以利用鸭子类型来做到这一点:
在,比如说,alice.py
文件中:
def do_stuff(data):
print 'alice does stuff with %s' % data
在,比如说,bob.py
文件中:
def do_stuff(data):
print 'bob does stuff with %s' % data
然后在你的主程序代码中,比如说,main.py
文件:
import threading
import alice, bob
def get_work_data():
return 'data'
def main():
tasks = [alice.do_stuff, bob.do_stuff]
data = get_work_data()
for task in tasks:
t = threading.Thread(target=task, args=(data,))
t.start()
如果需要我进一步解释,请告诉我。