zoukankan      html  css  js  c++  java
  • 并发编程之多进程篇之三

    基于多进程实现并发的套接字通信和守护进程

      一、关于进程之间内存的空间隔离

        看以下的两个实例,比较一下区别:

        实例一: 

    #!/usr/bin/env python3
    #-*- coding:utf-8 -*-
    # write by congcong
    from multiprocessing import Process
    '''
    a = 66
    def revise():
        global a
        a = 99
        print('修改后的值:a=%d'%a)
    if __name__ == '__main__':
        revise()
        print('全局的值a=%d'%a)'''
    
    '''输出的结果:
    修改后的值:a=99
    全局的值a=99

        实例二: 

    # 证明进程之间内存的空间隔离,各进程之间并不会相互影响
    n = 100
    def talk():
        global n
        n = 1
        print('子进程修改设置:%d '%n)
    
    if __name__ == '__main__':
        p = Process(target=talk)
        p.start() # 只是发送执行信号,并非立即执行
        p.join() # 只有p进程运行结束,才会运行其他进程
    
        print('main:%d'%n)
    '''未加p.join()时:
    main:100
    子进程修改设置:1 
    
    # 添加p.join()后:
    子进程修改设置:1 
    main:100
    '''

      由实例一和实例二可知:不同进程之间存在空间上的隔离,不会相互影响。

      二、多进程通信

        多进程通信以实例方式呈现,分为客户端和服务端。

        客户端.py   

    #!/usr/bin/env python3
    #-*- coding:utf-8 -*-
    # write by congcong
    
    from socket import *
    
    client = socket(AF_INET,SOCK_STREAM)
    client.connect(('127.0.0.1',3306))
    
    while True:
        msg = input('>>>:').strip()
        if not msg:continue
        client.send(msg.encode('utf-8'))
        data = client.recv(1024)
        print('from server:',data.decode('utf-8'))
    
    client.close()
    View Code

        服务端.py 

    #!/usr/bin/env python3
    #-*- coding:utf-8 -*-
    # write by congcong
    # 多进程并发通信
    from socket import *
    from multiprocessing import Process
    
    def talk(conn):
        while True:
            try:
                data = conn.recv(1024)
                if not data: break
                print('from client:',data.decode('utf-8'))
                conn.send(data.title())
            except  ConnectionResetError:
                break
        conn.close()
    
    def server(ip,port):
        server = socket(AF_INET, SOCK_STREAM)
        server.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
    
        server.bind((ip,port ))
        server.listen(5)
        while True:
            conn,addres = server.accept()
            p =  Process(target=talk,args=(conn,))
            p.start()
        server.close()
    if __name__ == '__main__':
        server('127.0.0.1',3306)
    View Code

      

      三、join方法的练习 

    #!/usr/bin/env python3
    #-*- coding:utf-8 -*-
    # write by congcong
    
    from multiprocessing import Process
    import time
    import random
    
    def task(n):
        time.sleep(random.randint(1,2))
        print('-----%s------'%n)
    
    if __name__ == '__main__':
        p1 = Process(target=task,args=(1,))
        p2 = Process(target=task,args=(2,))
        p3 = Process(target=task,args=(3,))
        p4 = Process(target=task,args=(4,))

      问题1:保证优先运行进程4 

        p4.start()
        p4.join()
        p1.start()
        p2.start()
        p3.start()
    
    #注意,放在if__name__=='__main__':下执行
        '''此时,保证优先运行进程4,并输出
        -----4------
        -----3------
        -----2------
        -----1------
        '''
    View Code

      问题2:保证按进程1、2、3、4顺序执行

        p1.start()
        p1.join()
        p2.start()
        p2.join()
        p3.start()
        p3.join()
        p4.start()
        p4.join()
    
    #同样放在if __name__ == '__main__':下运行
        '''此时保证按顺序输出
        -----1------
        -----2------
        -----3------
        -----4------   
        '''
    View Code

      

      四、守护进程

        1、理解:主进程创建子进程,然后将该进程设置成守护自己的进程,守护进程就好比崇祯皇帝身边的老太监,

        崇祯皇帝已死老太监就跟着殉葬了。

        2、注意:

          1️⃣:守护进程会在主进程代码执行结束后就终止;

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

          如果我们有两个任务需要并发执行,那么开一个主进程和一个子进程分别去执行就ok了,如果子进程的任务在主进程任务结束后就没有存在的必要了,

        那么该子进程应该在开启前就被设置成守护进程。主进程代码运行结束,守护进程随即终止。

        3、实例: 

    #!/usr/bin/env python3
    #-*- coding:utf-8 -*-
    # write by congcong
    from multiprocessing import Process
    import time
    def task(name):
        print('%s is running'%name)
        time.sleep(2)
        # p = Process(target=task,args=('进程2',))
        # p.start() 会报错--> 'daemonic processes are not allowed to have children' 守护进程不允许再有子进程
    if __name__ == '__main__':
        p = Process(target=task,args=('进程1',))
        p.daemon = True  # --->>  daemon表示守护进程,必须在进程启动前设置,在主进程结束后,也接着死亡
        p.start()
        p.join()
        print('主进程')
    '''
    进程1 is running
    主进程
    '''

        4、关于守护进程的练习,思考执行的结果是怎样的?

    import time
    from multiprocessing import Process
    def fun1():
        print(666)
        time.sleep(1)
        print('----fun1-----')
    def fun2():
        print(888)
        time.sleep(2)
        print('----fun2-----')
    if __name__ == '__main__':
        p1 = Process(target=fun1)
        p2 = Process(target=fun2)
    
        p1.daemon = True
        p1.start()
        p2.start()
        print('----main----')

      答案:

    ----main----
    888
    ----fun2-----
    View Code

        

  • 相关阅读:
    231. Power of Two
    204. Count Primes
    205. Isomorphic Strings
    203. Remove Linked List Elements
    179. Largest Number
    922. Sort Array By Parity II
    350. Intersection of Two Arrays II
    242. Valid Anagram
    164. Maximum Gap
    147. Insertion Sort List
  • 原文地址:https://www.cnblogs.com/schut/p/9011466.html
Copyright © 2011-2022 走看看