zoukankan      html  css  js  c++  java
  • 守护进程、互斥锁、进程间通信(IPC机制)

    1、windows:tasklist |findstr  进程id号

    2、mac,Linux:ps aux | grep  进程id号

    3、进程对象:t = Process(target = task,)或者在进程内部:current_process()

    4、t.pid或者current_process().pid  获取进程id号

    5、os.getpid() 同上获取进程ID号

    6、os.getppid() 获取父进程ID号,子进程中获取父进程ID,等于父进程的ID号

    7、t.is_alive()或者current_process().is_alive()  查看进程是否存活

    8、t.terminate()关闭进程,在主进程关闭

     

    二、守护进程

    主进程创建守护进程

      其一:守护进程会在主进程代码执行结束后就终止

      其二:守护进程内无法再开启子进程,否则抛出异常:AssertionError: daemonic processes are not allowed to have children

    注意:进程之间是互相独立的,主进程代码运行结束,守护进程随即终止

    例:代码


    from multiprocessing import Process,current_process
    import time
    import os

    def task():
       print(os.getpid())
       print('子进程')
       time.sleep(200)
       print('子进程结束')


    if __name__ == '__main__':
       t = Process(target=task, )
       # 守护进程:主进程一旦结束,子进程也结束
       # t.daemon=True # 一定要加在启动之前
       t.start()


       time.sleep(1)
       print('主进程结束')
    三、互斥锁

    进程之间数据不共享,但是共享同一套文件系统,所以访问同一个文件,或同一个打印终端,是没有问题的,

    而共享带来的是竞争,竞争带来的结果就是错乱,如何控制,就是加锁处理

    例:多个远程共享同一个打印终端

    #并发运行,效率高,但竞争同一打印终端,带来了打印错乱
    from multiprocessing import Process
    import os,time
    def work():
      print('%s is running' %os.getpid())
      time.sleep(2)
      print('%s is done' %os.getpid())

    if __name__ == '__main__':
      for i in range(3):
          p=Process(target=work)
          p.start()
    #由并发变成了串行,牺牲了运行效率,但避免了竞争
    from multiprocessing import Process,Lock
    import os,time
    def work(lock):
      lock.acquire()
      print('%s is running' %os.getpid())
      time.sleep(2)
      print('%s is done' %os.getpid())
      lock.release()
    if __name__ == '__main__':
      lock=Lock()
      for i in range(3):
          p=Process(target=work,args=(lock,))
          p.start()

    例:多个进程共享同一个文件  文件档数据库,模拟抢票

    #文件db的内容为:{"count":1}
    #注意一定要用双引号,不然json无法识别
    from multiprocessing import Process,Lock
    import time,json,random
    def search():
      dic=json.load(open('db.txt'))
      print('33[43m剩余票数%s33[0m' %dic['count'])

    def get():
      dic=json.load(open('db.txt'))
      time.sleep(0.1) #模拟读数据的网络延迟
      if dic['count'] >0:
          dic['count']-=1
          time.sleep(0.2) #模拟写数据的网络延迟
          json.dump(dic,open('db.txt','w'))
          print('33[43m购票成功33[0m')

    def task(lock):
      search()
      get()
    if __name__ == '__main__':
      lock=Lock()
      for i in range(100): #模拟并发100个客户端抢票
          p=Process(target=task,args=(lock,))
          p.start()
    文件db的内容为:{"count":1}
    #注意一定要用双引号,不然json无法识别
    from multiprocessing import Process,Lock
    import time,json,random
    def search():
      dic=json.load(open('db.txt'))
      print('33[43m剩余票数%s33[0m' %dic['count'])

    def get():
      dic=json.load(open('db.txt'))
      time.sleep(0.1) #模拟读数据的网络延迟
      if dic['count'] >0:
          dic['count']-=1
          time.sleep(0.2) #模拟写数据的网络延迟
          json.dump(dic,open('db.txt','w'))
          print('33[43m购票成功33[0m')

    def task(lock):
      search()
      lock.acquire()
      get()
      lock.release()
    if __name__ == '__main__':
      lock=Lock()
      for i in range(100): #模拟并发100个客户端抢票
          p=Process(target=task,args=(lock,))
          p.start()
    #加锁可以保证多个进程修改同一块数据时,同一时间只能有一个任务可以进行修改,即串行的修改,没错,速度是慢了,但牺牲了速度却保证了数据安全。
    虽然可以用文件共享数据实现进程间通信,但问题是:
    1.效率低(共享数据基于文件,而文件是硬盘上的数据)
    2.需要自己加锁处理



    #因此我们最好找寻一种解决方案能够兼顾:1、效率高(多个进程共享一块内存的数据)2、帮我们处理好锁问题。这就是mutiprocessing模块为我们提供的基于消息的IPC通信机制:队列和管道。
    1 队列和管道都是将数据存放于内存中
    2 队列又是基于(管道+锁)实现的,可以让我们从复杂的锁问题中解脱出来,
    我们应该尽量避免使用共享数据,尽可能使用消息传递和队列,避免处理复杂的同步和锁问题,而且在进程数目增多时,往往可以获得更好的可获展性。
    四、队列

    进程彼此之间互相隔离,要实现进程间通信(IPC),multiprocessing模块支持两种形式:队列和管道,这两种方式都是使用消息传递的

    例:代码



    from multiprocessing import Queue

    # 实例化得到要给对象

    q=Queue(5)  # 默认很大,可以放很多,写了个5,只能放5个

    # 往管道中放值
    q.put(1)
    q.put('lqz')
    q.put(18)
    q.put(19)
    # q.put(20)
    # q.put(21)
    # q.put_nowait(100)

    # 从管道中取值
    # print(q.get())
    # print(q.get())
    # print(q.get())
    # print(q.get(timeout=100)) # 等0.1s还没有值,就结束
    # print(q.get_nowait())       # 不等了,有就是有,没有就没有

    print(q.empty())  # 看一下队列是不是空的
    print(q.full())   # 看一下队列是不是满的


    # 总结:
    '''
    q=Queue(队列大小)
    # 放值
    q.put(asdf)
    q.put_nowait(asdf) # 队列满了,放不进去就不放了,报错

    # 取值
    q.get() # 从队列头部取出一个值
    q.get_nowait() # 从队列头部取值,没有就抛错


    # 队列是否为空,是否满
    print(q.empty()) # 看一下队列是不是空的
    print(q.full())   # 看一下队列是不是满的
    '''

    2、IPC机制(进程间通信)

    # Inter-Process Communication,进程间通信
    from multiprocessing import Process, current_process, Queue
    import time
    import os


    def task1(q):
       print('我是task1进程,我的id号是:%s'%os.getpid())
       q.put('lqz is handsome')


    def task2(q):

       # res=q.get()
       # print('我是task2进程,我的id号是:%s'%os.getpid(),res)
       print('我是task2进程,我的id号是:%s'%os.getpid())


    if __name__ == '__main__':
       q = Queue(5)

       t1 = Process(target=task1, args=(q,))
       t1.start()
       t2 = Process(target=task2, args=(q,))
       t2.start()

       print(q.get())


    每天逼着自己写点东西,终有一天会为自己的变化感动的。这是一个潜移默化的过程,每天坚持编编故事,自己不知不觉就会拥有故事人物的特质的。 Explicit is better than implicit.(清楚优于含糊)
  • 相关阅读:
    Java 泛型 泛型的约束与局限性
    Java 泛型 泛型方法
    Java 泛型 泛型数组
    Java 泛型 协变性、逆变性
    Java 泛型 协变式覆盖和泛型重载
    Java 泛型 泛型代码和虚拟机
    Insertion Sort List
    Remove Duplicates from Sorted List II
    String to Integer (atoi)
    SpringMvc源码入门
  • 原文地址:https://www.cnblogs.com/kylin5201314/p/13554007.html
Copyright © 2011-2022 走看看