• 进程通信


    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...')
  • 相关阅读:
    关于JS事件冒泡与JS事件代理(事件委托)
    异步、同步和阻塞、非阻塞
    大数据高并发
    前段clam安装
    JavaScript动态修改CSS
    键盘按键js效果
    键盘键值表总结
    移动端不可缩放
    JS基本语法
    计算几何——ICPC Latin American Regional Contests 2019 B
  • 原文地址:https://www.cnblogs.com/xuewei95/p/14864850.html
Copyright © 2020-2023  润新知