关于线程的真相-案例研究:机器人和餐具

案例研究:机器人和餐具

关于线程的真相-案例研究:机器人和餐具

其次,也是更重要的一点,我们过去(现在也仍然不相信)标准的多线程模型,它是共享内存抢占式并发:我们仍然认为没有人能够在“a = a + 1”是不确定的语言中编写正确的程序。

我讲了一个餐厅的故事,里面的类人机器人——ThreadBots——做了所有的工作。在这个比喻里,每个工人健康就是一个线程。在下面的案例中,我们将了解为什么线程被认为是不安全的。

# ThreadBot for table service
import threading
from queue import Queue
from attr import attrs, attrib # making class creation easy.

# attrs 初始化装饰器
@attrs
class Cutlery:
    knives = attrib(default=0)
    forks = attrib(default=0)

    def give(self, to:‘Cutlery‘, knives=0, forks=0):
        self.change(-knives, -forks)
        to.change(knives, forks)

    def change(self, knives, forks):
        self.knives += knives
        self.forks += forks

# Thread 子类
class ThreadBot(threading.Thread):
    tasks = Queue()
    def __int__(self):
        super().__init__(target=self.manage_table)
        # bot 等待table,同时响应cutlery
        self.cutlery = Cutlery(knives=0, forks=0)
        # 机器人还将被分配任务。它们将被添加到这个任务队列
        # 然后机器人将在其主处理循环期间执行它们
        # self.tasks = Queue()

    # 这个机器人的主要程序是这个无限循环。
    # 如果你需要关闭一个bot,你必须给他们关闭任务。
    def manage_table(self):
        while True:
            task = self.tasks.get()
            if task == ‘prepare table‘:
                kitchen.give(to=self.cutlery, knives=4, forks=4)
            elif task == ‘clear table‘:
                self.cutlery.give(to=kitchen, knives=4, forks=4)
            elif task == ‘shutdown‘:
                return



kitchen = Cutlery(knives=100, forks=100)
bots = [ThreadBot() for i in range(10)]  # 创建10个

import sys


for bot in bots:
    for i in range(int(sys.argv[1])):
        # print(bot,type(bot))
        bot.tasks.put(‘prepare table‘)
        bot.tasks.put(‘clear table‘)
    bot.tasks.put(‘shutdown‘)

print(‘Kitchen inventory before service: ‘, kitchen)
for bot in bots:
    bot.start()

for bot in bots:
    bot.join()
print("kitchen inventory after service: ", kitchen)