zoukankan      html  css  js  c++  java
  • (并发编程)进程 (multiprocessing--Process实现进程并发)

    ['创建进程2方式种',
    '进程对象属性:join方法,守护进程obj.daemon=True,obj.pid, obj.name, obj.terminate(),obj.is_alive()等 '
    'os.getpid,os.getppid',
    '互斥锁(Lock())',
    '僵尸进程与孤儿进程',
    '内存空间物理上隔离']
    并发的本质:切换+保持状态

    一、同一个程序执行多次是多个进程
    每一个进程有一个PID
    import os
    os.getppid()   #父的pid (pycharm.exe)#cmd 中 pyhon 路径 父的pid(cmd.exe)
    os.getpid()    #自己的pid (python.exe)
    二、开启子进程的两种方式
    windows (createprocess) 创建子进程时子辈除了拷贝父辈的信息还创建了些自己的东西
    unix (fork) 创建子进程时拷贝父辈的信息子进程的初始状态和父辈一致
    第一种(比较常用)                                                                                                                                                                                                           
    from multiprocessing import Process                                                                                                                                                                                 
    import time                                                                                                                                                                                                         
                                                                                                                                                                                                                        
    def task(name):                                                                                                                                                                                                     
        print('%s is running' %name)                                                                                                                                                                                    
        time.sleep(3)                                                                                                                                                                                                   
        print('%s is done' %name)                                                                                                                                                                                       
                                                                                                                                                                                                                        
    if __name__ == '__main__':                                                                                                                                                                                          
        # 在windows系统之上,开启子进程的操作一定要放到这下面                                                                                                                                                                                 
        # Process(target=task,kwargs={'name':'egon'})   #两种传参方式皆可                                                                                                                                                        
        p=Process(target=task,args=('egon',))          #两种传参方式皆可                                                                                                                                                        
        p.start() # 向操作系统发送请求,操作系统会申请内存空间,把父进程的数据拷贝给子进程,作为子进程的初始状                                                                                                                          
        print('======主')                                                                                                                                                                                                
                                                                                                                                                                                                                        
    第二种                                                                                                                                                                                                                 
    from multiprocessing import Process                                                                                                                                                                                 
    import time                                                                                                                                                                                                         
                                                                                                                                                                                                                        
    class MyProcess(Process):                                                                                                                                                                                           
        def __init__(self,name):                                                                                                                                                                                        
            super(MyProcess,self).__init__()     #Process在init里面有相应设置,要遗传下来,否则报错                                                                                                                                        
            self.name=name                                                                                                                                                                                              
                                                                                                                                                                                                                        
        def run(self):                                                                                                                                                                                                  
            print('%s is running' %self.name)                                                                                                                                                                           
            time.sleep(3)                                                                                                                                                                                               
            print('%s is done' %self.name)                                                                                                                                                                              
                                                                                                                                                                                                                        
    if __name__ == '__main__':                                                                                                                                                                                          
        p=MyProcess('egon')                                                                                                                                                                                             
        p.start()   #p.start()调用了类中的run()方法(规定)                                                                                                                                                                         
    print('主')
    三、进程的内存空间相互隔离
    from multiprocessing import Process                    
    import time                                            
                                                           
    x=1000                                                                                                       
    def task():                                            
        time.sleep(3)                                      
        global x                                           
        x=0                                                
        print('儿子死啦',x)                                    
    #在之前最好只有函数或变量的定义,没有具体的执行(print等)                                                       
    if __name__ == '__main__':                                                                      
        p=Process(target=task)                             
        p.start()                                          
        time.sleep(5)                                      
    print(x)    
    #在子进程中对变量x的修改不影响父进程中x的值
    四、父进程等待子进程结束 p1.join()
    #(等待p1 卡住)等儿子死了,wait回收儿子的pid等遗留下的东西
    #了解 连续start再连续join 和 连续start,join。。。。
    from multiprocessing import Process                                    
    import time                                                            
                                                                           
    x=1000                                                                                        
    def task(n):                                                           
        print('%s is runing' %n)                                           
        time.sleep(n)                                                      
                                                                           
    if __name__ == '__main__':                                             
        start_time=time.time()                                             
                                                                           
        p1=Process(target=task,args=(1,))                                  
        p2=Process(target=task,args=(2,))                                  
        p3=Process(target=task,args=(3,))                                  
        p1.start()                                                         
        p2.start()                                                         
        p3.start()                                                         
                                                                           
        p3.join() #3s                                                      
        p1.join()                                                          
        p2.join()                                                      
                                                                           
    print('主',(time.time() - start_time))        #3.01637601852417     
    #用循环
    from multiprocessing import Process                                  
    import time                                                          
                                                                         
    x=1000                                                               
                                                                         
    def task(n):                                                         
        print('%s is runing' %n)                                         
        time.sleep(n)                                                    
                                                                         
    if __name__ == '__main__':                                           
        start_time=time.time()                                           
        p_l=[]                                                           
        for i in range(1,4):                                             
            p=Process(target=task,args=(i,))                             
            p_l.append(p)                                                
            p.start()                                                    
                                                                         
        for p in p_l:                                                    
            p.join()                                                     
                                                                         
    print('主',(time.time() - start_time))       #3.0141923427581787
    五、进程对象的其他属性
    from multiprocessing import Process                                     
    import time                                                             
                                                                            
    def task(n):                                                            
        print('%s is runing' %n)                                            
        time.sleep(n)                                                       
                                                                            
    if __name__ == '__main__':   # 在windows系统之上,开启子进程的操作一定要放到这下面                                            
        start_time=time.time()                                              
        p1=Process(target=task,args=(1,),name='任务1') 
        p1daemon=True    #再obj发出创建前,将obj变成守护进程,主进程执行完毕后子进程跟着结束
        p1.start()         #向操作系统发创建子进程请求,父进程无需等待                                                    
        print(p1.pid)                                                       
        print(p1.name)     #如前面不定义name,默认process-1 etc                      
        p1.terminate()     #向操作系统发请求,父进程无需等待                            
        p1.join()          #等待该子进程结束(卡住吧),父进程需要等待一点时间                                                
        print(p1.is_alive())                                                
        print('主')       #这里的效果是主进程等儿子死了,再结束
    from multiprocessing import Process                         
    import time,os                                              
                                                                
    def task():                                                 
        print('self:%s parent:%s' %(os.getpid(),os.getppid()))  
        time.sleep(3)                                           
                                                                
    if __name__ == '__main__':                                  
        p1=Process(target=task,)                                
        p1.start()                                              
        print(p1.pid)                                           
    print('主',os.getpid())  
    六、僵尸进程与孤儿进程
    在unix系统中init是所有进程的爹;创建进程用fork,回收进程(结束进程的残留信息?)用waitpid
    僵尸进程(有害:占用pid):子代先于父代终结,其部分信息(pid等)没有从系统中删除,需要父代回收。join中含有回收子代信息的功能。
    孤儿进程(无害):父代先于子代终结,子代终结后的部分信息由init代收。
    from multiprocessing import Process                     
    import time,os                                          
                                                            
    def task(n):                                            
        print('%s is running' %n)                           
        time.sleep(n)                                       
                                                            
    if __name__ == '__main__':       
     1=Process(target=task,args=(1,))                   
        p1.start()                                          
        p1.join()     # join中含有回收子代信息的功能(wait)                                      
        print('======主',os.getpid()) 
     
     
    七、守护进程
    父进程  代码运行完(主线程运行代码),守护进程就结束
    from multiprocessing import Process
    import time
    def task(name):
        print('%s is running' % name)
        time.sleep(3)
    if __name__ == '__main__':
        obj = Process(target=task, args=('egon',))
        obj.daemon=True    #将obj变成守护进程,主进程执行完毕后子进程跟着结束
        obj.start()  # 发送信号给操作系统
      print('主')
    八、互斥锁
    强调:必须是lock.acquire()一次,然后 lock.release()释放一次,才能继续lock.acquire(),不能连续的lock.acquire()。否者程序停在原地。
         抢同一把锁:生成锁对象 必须放在if __name__=='__main__': 下面
    互斥锁vs join
    大前提:二者的原理都是一样,都是将并发变成串行,从而保证有序(在多个程序共享一个资源时,为保证有序不乱,需将并发变成串行)
    场景: 修改公共数据,如果并发会发出数据错乱,这时就必须串行执行,就要用到互斥锁
    区别一:join是按照人为指定的顺序执行,而互斥锁是所以进程平等地竞争,谁先抢到谁执行
    区别二:互斥锁可以让一部分代码串行,而join只能将代码整体串行(详见抢票系统)
      理解:首先join肯定是一个子进程对象,互斥锁可以加在子进程对象代码任意部位(要释放额)
         join人为安排子进程执行顺序,互斥锁是公平竞争。
      
    from multiprocessing import Process,Lock
    import time,random
    mutex=Lock()  #这里每个子进程的都会申请一把锁
    print(id(mutex))
    def task1(lock):
         lock.acquire()
     #   print('task1:名字是egon')
     #   time.sleep(random.randint(1,3))
     #   print('task1:性别是male')
         time.sleep(random.randint(1,3))      #with mutex: time.sleep(random.randint(1,3))
     #   print('task1:年龄是18')        
         lock.release()
    def task2(lock):
        lock.acquire()
        print('task2:名字是alex')
        time.sleep(random.randint(1,3))
        print('task2:性别是male')
        time.sleep(random.randint(1,3))
        print('task2:年龄是78')
        lock.release()
    def task3(lock):
        lock.acquire()
        print('task3:名字是lxx')
        time.sleep(random.randint(1,3))
        print('task3:性别是female')
        time.sleep(random.randint(1,3))
        print('task3:年龄是30')
        lock.release()
    if __name__ == '__main__':
        p1=Process(target=task1,args=(mutex,))
        p2=Process(target=task2,args=(mutex,))
        p3=Process(target=task3,args=(mutex,))
        p1.start()
        p2.start()
        p3.start()
    last、抢票系统
    import json
    import time
    import random
    import os
    from multiprocessing import Process,Lock
    mutex=Lock()  #每个子进程都会生成  一把锁对象,没用到。可以优化放在下面 __name__里面
    def search():
        time.sleep(random.randint(1,3))
        with open('db.json','r',encoding='utf-8') as f:
            dic=json.load(f)
            print('%s 剩余票数:%s' %(os.getpid(),dic['count']))
    def get():
        with open('db.json','r',encoding='utf-8') as f:
            dic=json.load(f)
        if dic['count'] > 0:
            dic['count']-=1
            time.sleep(random.randint(1,3))
            with open('db.json','w',encoding='utf-8') as f:
                json.dump(dic,f)
            print('%s 购票成功' %os.getpid())
    def task(lock):
        search()
        lock.acquire()
        get()
        lock.release()
    if __name__ == '__main__':
        for i in range(10):
            p=Process(target=task,args=(mutex,)) #这里子进程用的都是主进程这一把锁 id
            p.start()
  • 相关阅读:
    ASP.Net中实现XMl的标识列(ID列)或自增长列
    ASP.Net 更新储存在xml文件中的数据(update操作)
    系统分析师(1)网站介绍
    ASP.Net 删除xml文件中的数据(delete操作)
    DataGrid利用imagebutton实现更新操作
    DataGrid利用imagebutton实现删除操作
    JavaScript总结(1)Asp.Net 中利用JavaScript实现客户端验证
    sql server 2005 压缩实例下所有数据库文件及日志文件(转载)作者:Program Life
    Spreadsheet 对象
    多参数sp_executesql
  • 原文地址:https://www.cnblogs.com/3sss-ss-s/p/9592394.html
Copyright © 2011-2022 走看看