首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >多线程不能正确执行

问多线程不能正确执行
EN

Stack Overflow用户
提问于 2021-05-10 07:34:40
回答 2查看 75关注 0票数 0

我正在尝试使用多线程顺序运行两个函数(任务)。问题是,当我实现它时,会完全执行一个函数,然后进入另一个函数。我所期望的是,当循环在给定函数中完成其第一次运行时,跳转到另一个函数。

顺便说一句,我设置了time.sleep()来模拟一些订单的接收和准备场景。

代码语言:javascript
复制
from collections import deque
import time
from threading import Thread


class Order_queue:
    
    def __init__(self):
        self.buffer = deque()
    
    def place_order(self, basket):
        for item in basket:
            self.buffer.appendleft(item)
            print(f"Ordered: {item}")
            time.sleep(3)

        
    def serve_order(self):
        time.sleep(1)
        while not self.is_empty():
            served = self.buffer.pop()
            time.sleep(2)
            print(f"Served: {served}")


    def is_empty(self):
        return len(self.buffer)==0
    

order_list = ['pizza','samosa','pasta','biryani','burger']
order = Order_queue()


th1 = Thread(target=order.place_order, args=(order_list,))
th2 = Thread(target=order.serve_order)

th1.start()
th2.start()

th1.join()
th2.join()

输出:

代码语言:javascript
复制
Ordered: pizza
Ordered: samosa
Ordered: pasta
Ordered: biryani
Ordered: burger
Served: pizza
Served: samosa
Served: pasta
Served: biryani
Served: burger

预期:

代码语言:javascript
复制
Ordered: pizza
Served: pizza
Ordered: samosa
Served: samosa
....
EN

回答 2

Stack Overflow用户

发布于 2021-05-10 17:55:57

您不需要线程来连续运行两个函数(任务),因为它可以通过使用coroutines (一种非抢占式多任务的形式)来完成,在Python语言中创建它相对简单,因为它只需要在函数或方法中使用yield。

类似地,您不需要为任务提供deque或其他缓冲区,因为一次处理(即排序和服务)的任务不会超过一个。

下面是如何使用我建议的方法来实现这些东西。请注意,涉及的两个函数实际上不需要是class的一部分,但我将它们放在一个函数中,以使它们更像您问题中的代码。

代码语言:javascript
复制
import time


def coroutine(func):
    """ Decorator to make coroutines automatically start when called. """
    def start(*args, **kwargs):
        cr = func(*args, **kwargs)
        next(cr)
        return cr
    return start


class OrderQueue:

    @coroutine
    def serve_orders(self):
        while True:
            served = (yield)
            print(f'Served: {served}')
            time.sleep(2)

    def place_orders(self, basket):
        server = self.serve_orders()  # Initialize coroutine generator method.
        for item in basket:
            print(f'Ordering: {item}')
            server.send(item)
            time.sleep(0.5)
        server.close()  # Causes coroutine generator method to exit.


order_list = ['pizza', 'samosa', 'pasta', 'biryani', 'burger']

order_queue = OrderQueue()
order_queue.place_orders(order_list)

print('-- Fini --')

输出:

代码语言:javascript
复制
Ordering: pizza
Served: pizza
Ordering: samosa
Served: samosa
Ordering: pasta
Served: pasta
Ordering: biryani
Served: biryani
Ordering: burger
Served: burger
-- Fini --
票数 1
EN

Stack Overflow用户

发布于 2021-05-10 08:10:17

代码工作正常,正如@m_dubya所说的,place_order中的append和serve_order中的pop之间总共有3s睡眠。

例如,如果将place_order函数中的sleep更改为2秒,结果将为:

代码语言:javascript
复制
Ordered: pizza
Ordered: samosa
Served: pizza
Ordered: pasta
Served: samosa
Ordered: biryani
Served: pasta
Ordered: burger
Served: biryani
Served: burger
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67463206

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档