的 背景: 强> 因为Python本质上是单线程的(解释器由GIL或全局解释器锁保护),所以它没有真正的线程。相反,要实现相同的效果,您必须使用不同的过程,就像您在示例中所做的那样。因为这些是不同的进程,具有不同的解释器和不同的命名空间,所以您将无法从一个不同的进程访问一个进程中的普通数据。当您创建新进程时,python解释器会自行分配并复制所有Python对象,因此Car.car_list现在是两个不同的对象,每个进程一个。因此,当一个进程添加到该列表时,它将添加到与其他进程正在读取的列表不同的列表中。
的 回答: 强> 你的预感是正确的:你会想要使用多处理模块中的一个数据结构。这些数据结构被特别编写为“线程安全”(我猜在这种情况下实际上是“进程安全”)并且在幕后编组两个进程之间的共享数据。
的 例: 强> 您可以使用全局队列,其中“生产者”进程添加项目,“消费者”进程将其删除并将它们添加到其自己的列表副本中。
from multiprocessing import Queue class Car: global_queue = Queue() _car_list = [] # This member will be up-to-date in the producer # process. In that process, access it directly. # In the consumer process, call get_car_list instead. # This can be wrapped in an interface which knows # which process it is in, so the calling code does # not have to keep track. def __init__(self, id, model): self.id = id self.model = model self.global_queue.put(self) self._car_list.append(self) @classmethod def get_car_list(cls): """ Get the car list for the consumer process Note: do not call this from the producer process """ # Before returning the car list, pull all pending cars off the queue # while cls.global_queue.qsize() > 0: # qsize is not implemented on some unix systems while not cls.global_queue.empty(): cls._car_list.append(cls.global_queue.get()) return cls._car_list
注意:使用上面的代码,您只能拥有一个数据使用者。如果其他进程调用get_car_list方法,则它们将从队列中删除挂起的汽车,并且消费者进程将不会接收它们。如果您需要拥有多个消费者流程,则需要采用不同的方法。
如果您想要的只是计算您拥有的汽车数量,您可以使用共享内存对象 值 。
只需对代码进行一些更改,您就可以获得所需内容:
from multiprocessing import Process, Value import time class Car: car_list = list() car_quantity = Value('i', 0) # Use a shared memory object here. def __init__(self, id, model): self.id = id self.model = model Car.car_list.append(self) Car.car_quantity.value += 1 # Update quantity @classmethod def get_current_instances(cls): return Car.car_list class Interface: def print_current_system(self): while True: print(Car.car_quantity.value) # Just print the value of the memory shared object (Value). time.sleep(1) if __name__ == "__main__": interface = Interface() model = ["Toyota", "BMW"] [Car(i, model[i]) for i in range(len(model))] print_process = Process(target=interface.print_current_system) print_process.start() time.sleep(3) # Added here in order you can see the # ouptut changing from 2 to 3. Car(2345, "Tesla") print("from main process " + str(len(Car.get_current_instances())))
输出:
2 2 2 from main process 3 3 3 3 3 3