• 获取进程id和名字[getpid()--is_terminate()]--结束进程和判断运行[is_alive()--is_alive]--守护线程[daemon()]--进程锁[Lock()]--队列[Queue()--JoinableQueue()]--数据共享[Manager]


    一、如何获取进程的id号和进程的名字.

    os.getpid() #获取本进程的id号

    os.getppid() #获取本进程的父进程的id号

    import os
    from multiprocessing import Process
    def f1():
        print('f1进程的pid',os.getpid())
        print('f1进程的父进程的pid',os.getppid())
    if __name__ == '__main__':
        p1 = Process(target=f1,name='欢迎')
        p1.start()
        print(p1.name)
        print('p1进程的pid',p1.pid)
        print('本进程的id',os.getpid())
    # p1.pid #返回结果为p1进程的id号
    # os.getpid()#返回本进程的id号
    # os.getppid()#返回为本进程的父进程id号
    # p1.name()#返回p1进程的名字

    二、如何手动结束子进程,以及判断子进程是否还在运行

    obj.is_terminate()  #给操作系统发送结束进程的信号

    obj.is_alive()  #判断进程是否在运行,返回值True,False

    import time
    from multiprocessing import Process
    def f1():
        print('子进程1号')
    if __name__ == '__main__':
        p = Process(target=f1,)
        p.start()
        print(p.is_alive())  #判断子进程是否还活着,是否还在运行
        p.terminate() #给操作系统发送一个结束进程的信号
        time.sleep(0.5) #需要延迟一会再判断是否还存活,因为系统结束进程需要处理很多东西
        print(p.is_alive())

    三、如何验证进程存在空间隔离

    对于打印结果的解释:首先程序自上往下走,先打印一遍100,开启子进程后,系统copy一份代码走,并运行,又打印一遍100,子进程修改的只是自己进程里的全局变量,

    而父进程的变量还是那个,这就验证了进程之间存在空间隔离.

    from multiprocessing import Process
    num = 100
    def f1():
        global num
        num = 3  #修改全局变量的值
        print('f1进程中的num',num)
    print('>>>>>',num)
    if __name__ == '__main__':
        p = Process(target=f1,)
        p.start()
        p.join()
        print('主进程中的num',num)
    打印结果为:
    >>>>> 100
    >>>>> 100
    f1进程中的num 3
    主进程中的num 100

    四、关于守护进程

    obj(进程的实例化对象).daemon = True       #开启守护进程,一定要在开启进程( obj.start() )前设置
    什么是守护进程:
      1.在主进程代码执行结束后就终止(应用场景:子进程需要跟父进程一起结束时)
      2.守护进程内无法开启子进程,否则抛异常
    from multiprocessing import Process
    def f1():
        print("xxx")
    def f2():
        print("p普通子进车")
    if __name__ == '__main__':
        p = Process(target = f1,)
        p.daemon = True  #开启守护进程,一定要在开启该进程(p.start())前设置,父进程代码执行结束,这个守护进程也结束.
        p.start()
        #p.join()  #给主进程阻塞,守护进程有机会执行里面的代码
        print("主进程结束.")
        p2 = Process(target = f2,) #普通进程不受限制
        p2.start()

    五、关于僵尸进程和孤儿进程概念

    僵尸进程:在子进程执行完,而主进程还没有执行完的时候,系统会保留执行的子进程一些信息(id号,名字...),它会随着主进程的结束而被清理掉

    孤儿进程:主进程在子进程前结束了,这个时候该子进程的一些信息没人管了,就叫孤儿进程,最后会被系统清理.

    六、关于互斥锁进程锁同步锁:

    什么时进程所互斥锁同步锁:  控制进程在共享一个文件,或同一个打印终端的时候,产生竞争时的错乱.原理是把并发改成串行
    with obj(锁的实例化对象): #简易写法
      需要上锁的代码
    
    Lock.acquire() #加锁
    Lock.release() #解锁
    from multiprocessing import Process,Lock
    import time
    def show_t(i):
        with open("ticket","r",encoding = "utf-8")as f:  #用with open打开文件,前2个可以用位置参数,但第三个必须用关键字传参
            ticket_data = f.read()
            t_data = eval(ticket_data)
            print("%s查询剩余票数为%s"%(i,t_data["count"]))
    def get_t(i,l1):
        # l1.acquire()#加锁
        with l1: #用了该枷锁方法,就不用手动解锁了
            with open("ticket","r",encoding="utf-8")as f:
                ticket_data = f.read()  #ticket票 data数据
                t_data = eval(ticket_data)
            if t_data["count"]>0:
                t_data["count"]-=1
                print("%s抢票成功"%i)
                time.sleep(0.2)
                with open("ticket","w")as f:
                    f.write(str(t_data))
            else:
                print("没有票了")
        # l1.release()  #解锁
    if __name__ == '__main__':
        l1 = Lock()
        for i in range(10):
            p1 = Process(target=show_t,args=(i,))
            p1.start()
        for i in range(10):
            p2=Process(target=get_t,args=(i,l1)) #传两个参数要加括号
            p2.start()

    七、关于multiprocessing包的Queue模块的使用

    方法介绍:
    obj.put()  #往队列里面放数据,如果队列里面满了,会阻塞
    obj.put_nowait() #满了就报错(不会阻塞程序,可以通过捕获异常来进行其他的操作)
    obj.get()   #从队列里面取数据,如果队列里面空了,会阻塞(等待)
    obj.get_nowait()    #空了就报错(不会阻塞程序,可以通过捕获异常来进行其他的操作)
    obj.full()   #查看队列是否满了,满了返回True,但该命令的执行速度比put和get的速度快,所以结果不准确
    obj.empty()  #查看队列是否空了,空了返回True,结果同理,有时不准确
    obj.qsize()  #返回当前队列内容的长度,结果也不准确

    举例:关于Queue

    from multiprocessing import Process,Queue
    def f1(q):
        q.put('约吗?')
    if __name__ == '__main__':
        q = Queue(3)
        p = Process(target=f1,args=(q,))
        p.start()  #开启子进程
        son_p_msg = q.get()  #从队列里面拿数据,队列为空,则阻塞等待
        print('来自子进程的消息:',son_p_msg)

    八、JoinableQueue方法(跟Queue相近)

    JoinableQueue的实例p除了与Queue对象相同的方法之外还具有:
    方法介绍: q.task_done():使用者使用此方法发出信号,表示q.get()的返回项目已经被处理。如果调用此方法的次数大于从队列中删除项目的数量,将引发ValueError异常         下面例子中,应用此方法目的,是为了解决,当有多个消费者程序,去队列里拿数据的时候,不知道队列里是否空了,而此方法,会往队列里面放入一个信号,表示该数据被拿走了. q.join():生产者调用此方法进行阻塞,直到队列中所有的项目均被处理。阻塞将持续到队列中的每个项目均调用q.task_done()方法为止
    import time
    from multiprocessing import Process,Queue,JoinableQueue
    #生产者
    def producer(q):
        for i in range(10):
            time.sleep(0.2)
            s = '大包子%s号'%i
            print(s+'新鲜出炉,拿去用')
            q.put(s)
        q.join() #等待的是队列的内容处理完毕(q是队列的实例化对象),而不是等待上面代码执行,就等着task_done()信号的数量,和我put进去的数量相同时,才继续执行下面代码
    print('所有的任务都被处理了,继续潜行吧骚年们')
    #消费者
    def consumer(q):
        while 1:
            time.sleep(0.5)
            baozi = q.get()
            print(baozi+'被吃了')
            q.task_done()  #给队列发送一个取出的这个任务已经处理完毕的信号
    if __name__ == '__main__':
        # q = Queue(30)
        q = JoinableQueue(30) #同样是一个长度为30的队列
        pro_p = Process(target=producer,args=(q,))
        con_p = Process(target=consumer,args=(q,))
        pro_p.start()
        con_p.daemon = True #开启守护进程,消费者会随着主进程的结束而终结
        con_p.start()
        pro_p.join()  #让主进程等待(生产者)子进程
        print('主进程结束')

     九、Manager方法

    什么是Manager方法:
    Manager是是一种数据共享的方法.一种较为高级的多进程通信方式
    进程之间的通信:队列、管道、数据共享(Manager). 
      队列,管道,这些方式只适用于多个进程都是源于同一个父进程的情况。如果多个进程不是源于同一个父进程,只能用共享内存,信号量等方式,还有就是数据共享(Manager) 多进程共同去处理共享数据的时候,就和我们多进程同时去操作一个文件中的数据是一样的,不加锁就会出现错误的结果,进程不安全的,所以也需要加锁
    import time
    from multiprocessing import Process,Manager,Lock #创建进程的方法数据共享的方法互斥锁方法
    def f1(m_d,l2):
        with l2:
            tmp = m_d["num"]
            tmp -= 1
            time.sleep(0.1)
            m_d["num"]=tmp
    if __name__ == '__main__':
        m = Manager()  #实例化数据共享的对象
        l2 = Lock  #实例化锁的对象
        m_d = m.dict({"num":100})
        p_list = []
        for i in range(10):
            p = Process(target=f1,args=(m_d,l2))
            p.start()
            p_list.append(p)
        [pp.join() for pp in p_list]
        print(m_d["num"])
  • 相关阅读:
    ORA00845 MEMORY_TARGET not supported on this system (oracle11g for asianux3 )
    文件处理命令
    网络通信
    Chapter05Usage and Configuration of the Oracle Shared Server
    压缩解压缩命令
    PAT 1088 Rational Arithmetic[模拟分数的加减乘除][难]
    知识点最小二乘学习与正规表达式
    Missing Number[回溯][难]
    PAT 1065 A+B and C[大数运算][溢出]
    PAT 1055 The World's Richest[排序][如何不超时]
  • 原文地址:https://www.cnblogs.com/lgw1171435560/p/10243622.html
Copyright © 2020-2023  润新知