import multiprocessing, time '''Process类其它方法及属性''' # class MyProcess(multiprocessing.Process): # def __init__(self, city): # super(MyProcess, self).__init__(name='进程') # self.city = city # # def run(self): # print(self.name) # 进程名,默认是类名 # print(self.is_alive()) # 进程是否在运行 # print(self.pid) # 进程ID,等于os.getpid() # # if __name__ == '__main__': # l = [] # for p in range(4): # p = MyProcess('China') # p.start() # l.append(p) # for p in l: # p.join() '''进程间的通信''' # 进程队列Queue # def foo(q): # q.put(1) # 子进程运行此函数,队列q传了过来,所以可进行put操作 # q.put('alex') # q.put({'name': 'mike'}) # # def func(q): # time.sleep(3) # while True: # try: # data = q.get_nowait() # print(data) # except Exception: # break # # if __name__ == '__main__': # q = multiprocessing.Queue() # multiprocessing模块下的Queue()类 # p = multiprocessing.Process(target=foo, args=(q,)) # 不同进程间通信需要把队列q当作参数传输 # p.start() # p2 = multiprocessing.Process(target=foo, args=(q,)) # 不同进程间通信需要把队列q当作参数传输 # p2.start() # p1 = multiprocessing.Process(target=func, args=(q,)) # p1.start() # p1.join() # print('end...') # 线程是在进程里面,队列或全局变量都可以共享;而进程各个都是独立,想要通信数据,那么必须要有一个传输 # 管道Pipe,Pipe()函数返回一个由管道连接的连接对象,默认情况下是双工(双向)。返回的两个连接对象 Pipe() 表示管道的两端。每个连接对象都有 # send() 和 recv() 方法(相互之间的)。请注意,如果两个进程(或线程)同时尝试读取或写入管道的同一端,则管道中的数据可能会损坏。当然, # 在不同进程中同时使用管道的不同端的情况下不存在损坏的风险。 # def foo(conn): # conn.send([42, None, 'hello']) # # send(obj)将一个对象发送到连接的另一端,可以用 recv() 读取 # print(conn.recv()) # # recv()返回一个由另一端使用 send() 发送的对象 # conn.close() # # close()关闭连接对象 # # if __name__ == '__main__': # parent_conn, child_conn = multiprocessing.Pipe() # p = multiprocessing.Process(target=foo, args=(child_conn,)) # p.start() # print(parent_conn.recv()) # parent_conn.send({'name':'alex'}) # p.join() # 管道和队列(进程之间的两种通信通道,并非共享数据(一方修改另一方也会有相应变化)),使用多进程时,一般使用消息机制实现进程间通信,尽可能避免使用同步原语,例如锁。 # 消息机制包含:Pipe()(可以用于在两个进程间传递消息),以及队列(能够在多个生产者和消费者之间通信)。 # multiprocessing.Manager()返回一个已启动的 SyncManager 管理器对象,这个对象可以用于在不同进程中共享数据。返回的管理器对象对应了一个已经启动的子进程,并且拥有一系列方法可以用于创建共享对象、返回对应的代理。当管理器被垃圾回收或者父进程退出时,管理器进程会立即退出 # 服务进程,由 Manager() 返回的管理器对象控制一个服务进程,该进程保存Python对象并允许其他进程使用代理操作它们。 # Manager() 返回的管理器支持类型: list 、 dict 、 Namespace 、 Lock 、 RLock 、 Semaphore 、 BoundedSemaphore 、 Condition 、 Event 、 Barrier 、 Queue 、 Value 和 Array # 使用服务进程的管理器比使用共享内存对象更灵活,因为它们可以支持任意对象类型。此外,单个管理器可以通过网络由不同计算机上的进程共享。但是,它们比使用共享内存慢。 def foo(d, l, n): d[n] = '1' l.append(n) d['2'] = 2 # print('son process:', id(d), id(l)) if __name__ == '__main__': with multiprocessing.Manager() as manager: d = manager.dict() # 创建一个共享的 dict 对象并返回它的代理 l = manager.list() # 创建一个共享的 list 对象并返回它的代理 num = manager.Namespace() # 命名空间对象没有公共方法,但是拥有可写的属性。直接print会显示所有属性的值。 num.x = 20 l1 = [] for t in range(10): p = multiprocessing.Process(target=foo, args=(d, l, t)) p.start() l1.append(p) for i in l1: i.join() print(d) print(l) print(num)