多个线程具有相同的协程?

时间:2015-01-07 08:21:39

标签: python multithreading coroutine

我可以运行多个线程来运行协程的相同副本吗?

例如,如果我将线程函数从此tutorial更改为

@coroutine
def threaded(count, target):
    messages = Queue()
    def run_target():
        while True:
            item = messages.get()
            if item is GeneratorExit:
                target.close()
                return
            else:
                target.send(item)

    for i in xrange(count):
        Thread(target=run_target).start()

    try:
        while True:
            item = (yield)
             messages.put(item)
     except GeneratorExit:
         messages.put(GeneratorExit)

这真的有用吗?如何验证它是否正常工作?

1 个答案:

答案 0 :(得分:0)

我认为我已经解决了这个问题,我需要将功能改为这样的功能

@coroutine
def _threaded(self, count, target_func):
    """
    Given a target coroutine, spawn $count threads to run copies of them. In
    order to properly use this, do not call the coroutine before calling this,
    e.g.

        @coroutine
        def foo(self):
            ...

        def bar(self):
            ...
            self._threaded(10, self.foo)    # <- do not call self.foo,
                                            # just the reference

    @param count        The number of threads to spawn
    @param target_func  The reference to the target coroutine
    @returns            The subnet mask
    """
    result = None

    messages = Queue()

    def default_target_run(index):
        target = target_func()
        while True:
            item = messages.get()
            if item is GeneratorExit:
                target.close()
                return
            else:
                target.send({'index': index, 'item': item})

    # ensure code is testable
    target_run = default_target_run
    try:
        target_run = self._threaded.target_run
    except AttributeError:
        pass

    result = ThreadPool(count).map_async(target_run, range(count))

    try:
        while True:
            item = (yield)
            messages.put(item)
    except GeneratorExit:
        # allow all threads to quit
        # by making sure all of them receives the exit message
        for i in xrange(count):
            messages.put(GeneratorExit)

    result.ready()