zoukankan      html  css  js  c++  java
  • 35 并行/发 同/异步 非/阻塞 开进程的两种方式, 进程的常用方法及属性 使用进程实现socket聊天

    主要内容:

     1  名词解释

      并行 :  即两件事情或多件事情,在同一时间点同时执行.是从微观上,也就是在一个精确的时间片刻有不同的程序在执行,这就要求必须有多个处理器

      并发 :  即两件事情或多件事情在同一时间段交替进行. 是从宏观上,在一个时间段上可以看出是同时执行的,比如一个服务器同时处理多个session。

      同步 :  所谓同步就是一个任务的完成需要依赖另外一个任务时,只有等待被依赖的任务完成后,依赖的任务才能算完成,这是一种可靠的任务序列。要么成功都成功,失败都失败,两个任务的状态可以保持一致。

      异步所谓异步是不需要等待被依赖的任务完成,只是通知被依赖的任务要完成什么工作,依赖的任务也立即执行,只要自己完成了整个任务就算完成了。至于被依赖的任务最终是否真正完成,依赖它的任务无法确定, 所以它是不可靠的任务序列.

      阻塞 :  阻塞(Blocked)状态正在执行的进程,由于等待某个事件发生而无法执行时,便放弃处理机而处于阻塞状态。引起进程阻塞的事件可有多种,例如,等待I/O完成(input)、申请缓冲区不能满足、等待信件(信号)等

    2 . 开启进程两种方式

      1) 第一种

    from multiprocessing import Process
    import os
    import time
    def func(i):
        time.sleep(0.2)
        print('这是子进程%s,pid为%s ,其父进程的pid为%s' % (i, os.getpid(), os.getppid()))
    # os.getpid(), 获得当前进程的pid,
    # os.getppid(),获得当前进程的父进程的pid
    if __name__ == '__main__':
        for i in range(2):
            p = Process(target=func, args=(i,))   #实例化一个进程对象
            #target:子进程要执行的任务,args:父进程要给子进程传递的参数,必须是元祖形式.
            p.start()                            #开启一个进程.
            time.sleep(0.2)
        print('这是父进程, pid为%s, 其父进程的pid为%s' % (os.getpid(), os.getppid()))
    

      2) 继承

    from multiprocessing import Process
    import time
    import os
    class Myprocess(Process):
        def __init__(self):
            super(Myprocess, self).__init__()
        def run(self):
            print('在类中创建子进程')
    if __name__ == '__main__':
        p = Myprocess()
        p.start()       #是指解释器告诉操作系统, 去帮我开启一个进程, 就绪状态
        p.run()         # 解释器告诉操作系统,马上帮我执行这个过程.   执行状态
    

        带名字的

    from multiprocessing import Process
    import time
    import os
    class Myprocess(Process):
        def __init__(self, name):
            self.name = name
            super(Myprocess, self).__init__(name = name)   # 如果不写在执行父类中的__init是name会被覆盖.
        def run(self):
            print('这是以类的方式开启的子进程, 名字为%s' % self.name)
    if __name__ == '__main__':
        p = Myprocess('alex')
        p.start()       #是指解释器告诉操作系统, 去帮我开启一个进程, 就绪状态.
        # p.run()       # 解释器告诉操作系统立即去开启一个进程, 执行状态.
    

    3 . 进程的常用方法:

      1) start 和join

        join : 是让主进程等待子进程执行完再执行

    from multiprocessing import Process
    import os
    import time
    def func():
        for i in range(100):
            time.sleep(0.1)
            print('这是子进程')
    if __name__ == '__main__':
        p = Process(target=func)   #子进程要执行的任务
        p.start()
        # p.join()                   #是让主进程等待子进程执行完, 现象 : 主进程走到这句话, 主进程阻塞住, 等待子进程执行完.
        for i in range(100):
            time.sleep(0.1)
            print('这是父进程')
    # 开启一个正常的子进程,父进程会等待子进程结束后,父进程也就是程序才结束
    # p.join()# 是让主进程等待子进程执行完。  现象:主进程执行到这句话,主进程阻塞住,等待子进程执行
    # 如何把父进程和子进程之间的关系变为同步或者异步?
    # 父进程执行join,就会变成同步,不执行join,父进程和子进程就是异步的关系
    # join必须放在start()后边
    

      jion

    from multiprocessing import Process
    import time
    import random
    def func(i):
        time.sleep(1)
        print('我是%s'%i)
    if __name__ == '__main__':
        l = []
        addr = ['河南的','山东的','辽宁的','湖南的']
        for i in addr:
            p = Process(target=func,args=(i,))       #实例化一个进程对象
            p.start()
            p.join()#开启一个进程
            l.append(p)
        for k in l:   [k.join() for k in l]
            k.join()    #此时这四个进程已经开启,同时jion, 
        time.sleep(1)
        print('我选%s'%(random.choice(addr)))
    

      2) is_alive 和terminate

    def func():
        time.sleep(1)
    if __name__ == '__main__':
        p = Process(target=func,)
        p.start()
        p.terminate()# 杀死p进程,让解释器告诉操作系统,请杀掉p进程。
        print('子进程是否还活着?', p.is_alive())
        time.sleep(0.002)
        print('子进程是否还活着?', p.is_alive())
        # 返回一个bool值,如果返回True,代表进程还活着,如果返回False,代表子进程死了
    # p.is_alive() 判断p进程是否还活着
    # p.terminate() 杀死p进程
    

    4 . 进程的常用属性:

      1)  name 和 pid

    from multiprocessing import Process
    import time
    import os
    def func():
        print('这是子进程, pid为%s' % os.getpid())
    if __name__ == '__main__':
        p = Process(target=func)
        p.start()
        p.name = 'alex'
        print('可以查看子进程的pid',p.pid)
        print('可以查看子进程的名字', p.name)
        print('子进程是不是守护进程', p.daemon)   false
    

      2 ) 守护进程

        特点 : 将进程设置为守护进程 , 必须在start之前 daemon = false

           守护进程会随着主进程的结束而结束

           守护进程不能有子进程.

        **守护进程会随着主进程的结束而结束

    from multiprocessing import Process
    import time
    def func():
        time.sleep(3.1)
        print('this is son process')
    if __name__ == '__main__':
        p = Process(target=func)
        p.daemon = True       #必须在start之前设置
        p.start()
        time.sleep(3)
        print('this is parent process')
    #守护进程会随着主进程的结束而结束.
    

           **守护进程不能有子进程

    from multiprocessing import Process
    import time
    def func1():
        print('这里是孙子')
    def func():
        p = Process(target=func1)
        p.start()
        time.sleep(5)
        print('这里是儿子哦')
    if __name__ == '__main__':
        p = Process(target=func)
        p.daemon = True # 将p进程设置为守护进程,必须要在start之前设置
        p.start()
        time.sleep(1)
        print('这是爸爸')
    # 守护进程:不允许开启子进程
    

    5 . 

    from multiprocessing import Process
    import time
    import sys
    def func():
        print(sys.modules[__name__].__name__)
    print(123)
    if __name__ == '__main__':
        p = Process(target=func)
    #当程序运行到这一句时, 会把全部内容复制放在一块内存中,
        p.start()   # 开启一个子进程
        print('hahhh')
    #  程序从上往下执行, 先打印一个123, 然后主程序执行到p = process() 会把全部的内容复制到一块内存中, 
    # 然后p.start开始运行, 程序从上到下一次执行, 运行到if语句时结束.因为此时的__name = _mp_main_,条件不成立所以打印了两次123.
    

    6 . 用进程实现socket聊天

      服务器端代码:

    from multiprocessing import Process
    import socket
    sk = socket.socket()
    sk.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
    sk.bind(('127.0.0.1',9990))
    sk.listen(5)
    def talk(conn):
        while 1:
            try:
                msg = conn.recv(1024).decode('utf-8')
                if not msg:break
                conn.send(msg.upper().encode('utf-8'))
            except Exception:
                break
    if __name__ == '__main__':
        while 1:    #(在此加上while, 可以实现一个服务器与多个客户端进行通信)
            conn, addr = sk.accept()
            p = Process(target=talk, args = (conn, ))
            p.start()

      客户端代码:

    import socket
    sk = socket.socket()
    sk.connect(('127.0.0.1', 9990))
    while 1:
        content = input('请输入内容>>>')
        if not content:continue
        sk.send(content.encode('utf-8'))
        msg = sk.recv(1024).decode('utf-8')
        print(msg)
    

      

      

      

  • 相关阅读:
    js随机生成
    黑客代码雨效果
    HTML5 <details> 标签
    fieldset标签——使用(很少使用)
    jQuery总结
    vue element Cascader 级联选择器 选择任意一级选项 点击收起,点击label选中等问题详解
    Vue、element-ui的resetFields()方法重置表单无效问题及解决办法
    常用正则表达式(字符)
    一、日常经验记录
    python-opencv学习第二章
  • 原文地址:https://www.cnblogs.com/gyh412724/p/9507072.html
Copyright © 2011-2022 走看看