在python中产生一个线程

mor*_*ous 22 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)
Run Code Online (Sandbox Code Playgroud)

没有猜测的奖品我还在用C++思考.如何使用Pythonic'enums'和'switch'以Pythonic方式编写它,并能够在新线程中运行模块.

显然,这些模块都有一个派生自一个名为Plugin的ABC(抽象基类)的类.spawnWorker()方法将在Plugin接口上声明,并在各种模块中实现的类中定义.

也许,有一种更好的(即Pythonic)做这一切的方式?我有兴趣知道

[编辑]

我刚刚读了一个机器人,似乎Python没有真正意义上的线程实现(至少,不是C++程序员会想到的意义).在任何情况下,这对我来说都不是一个限制.每个任务都相当耗时,我不想阻止启动一个任务直到另一个任务完成,这就是我使用线程的原因.时间切片并不会让我感到烦恼 - 只要它们几乎同时启动(或者不久之后),Python就可以在它们之间尽可能多地进行时间间隔 - 这对我很好.

我在SO上看到了类似问题的答案.

用户提供了一个简单的线程类,如下所示:

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()
Run Code Online (Sandbox Code Playgroud)

我正在考虑将此用于我的ABC插件.那么我的问题是我将代码放在实际任务完成的位置(即业务逻辑).我假设这是在Foo类的run()方法中(我知道明显的问题,但我不想做任何假设).

我的想法是在正确的轨道上还是有缺陷的(如果有缺陷 - 我错过了什么?)

San*_*nta 37

而不是switch-case,为什么不使用适当的多态?例如,在这里您可以使用Python中的duck typing进行操作:

在比方说alice.py:

def do_stuff(data):
    print 'alice does stuff with %s' % data
Run Code Online (Sandbox Code Playgroud)

在比方说bob.py:

def do_stuff(data):
    print 'bob does stuff with %s' % data
Run Code Online (Sandbox Code Playgroud)

然后在您的客户端代码中,例如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()
Run Code Online (Sandbox Code Playgroud)

如果我需要澄清,请告诉我.

  • 请注意,如果`data`碰巧是可变的,你会想要将副本传递给每个Thread,或者传递一个锁对象(http://docs.python.org/library/threading.html#lock) -objects). (8认同)

nkr*_*rkv 5

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()
Run Code Online (Sandbox Code Playgroud)

将您的逻辑放在do_work相应模块的功能中.