进程通信

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)
while True: print('studying...')
原文地址:https://www.cnblogs.com/xuewei95/p/14864850.html