python学习day36笔记

进程的并行和并发

并行:两者同时执行。在微观上。两者在精确时间片刻同时进行
并发:资源有限的情况下,两者交替轮流使用资源。在宏观上,一段时间内两者同时进行

同步异常与阻塞非阻塞

同步和异步关注的是消息通信机制
同步:一个任务的完成需要依赖另一个任务时,只有等待被依赖的任务完成后,依赖的任务才算完成,这是一种可靠的任务序列,两个任务的状态保持一致
异步:不需要等待被依赖的任务完成,只是通知被依赖的任务要完成什么工作,依赖的任务也立即执行,只要自己完成了整个任务就算完成了。依赖它的任务无法确定被以来的任务是否完成,所以它是不可靠的任务序列

阻塞和非阻塞关注的是程序在等待调用结果(消息,返回值)时的状态
阻塞:阻塞调用是指调用结果返回之前,当前线程会被挂起。函数只有在得到结果之后才会返回
非阻塞:非阻塞和阻塞的概念相对应,指在不能立刻得到结果之前,该函数不会阻塞当前线程,而会立刻返回

同步与阻塞的区别:对于同步调用来说,很多时候当前线程还是激活的,只是从逻辑上当前函数没有返回而已。当socket工作在阻塞模式的时候, 如果没有数据的情况下调用该函数,则当前线程就会被挂起,直到有数据为止。简单的说就是同步时进程还在内存等待函数返回值,阻塞时线程被阻塞挂起到外存等待,直到函数返回值。
阻塞挂起状态:进程在外存并等待某事件的出现。

如何开启进程

Process类

from multiprocessing import Process

def write():
    with open('abc','a')as f:
        f.write('ly is sb')
        f.write('\n')

if __name__ = '__main__':  # windows中想开启进程,必须放在main里面
    p = Process(target=write)  # 1.实例化得到进程对象赋给对象p
    # process传入参数target
    # target -> 你要执行的任务(可以理解成函数)
    # 意思是通知操作系统开启进程
    p.start()  # 2.必须调用start方法

Process参数

target=None, name=None, args=(), kwargs={}
target -> 你要执行的任务  # 意思是通知操作系统开启进程
name -> 进程名  # 输出当前的进程名,可对其进行操作
args -> 传给target指向的任务  # 传的是位置参数
kwargs -> 传给target指向的任务  # 传的是关键字参数

Process类的方法

p.start()  # 开启进程必须使用的,运行主进程中途不等待子进程
p.run()  # 调用run方法不会启动子进程
p.join()  # 等待子进程执行完毕,再执行主进程
p.terminate()  # 杀死进程用
p.is_alive()  # 判断进程是否活着,返回布尔值,如果执行太快会返回之前的布尔值

Process类的属性

p.name  # 进程名
p.pid  # 进程id号
p.ppid  # 父进程id号
p.daemon = True  # 设置守护进程,主进程结束,子进程也结束,强调:必须放在start之前

获取进程id号

from multiprocessing import Process
import os

def write():
    print('子进程的id号:%s'%os.getpid())
    print('父进程的id号:%s'%os.getppid())

if __name__ == '__main__':
    p = Process(target=write)
    p.start()
    print(p.pid)
    print("main_主进程的id号:%s"%os.getpid())
    print('main_父进程的id号:%s'%os.getppid())

同时运行多个进程

from multiprocessing import Process
import time
def write(i):
    time.sleep(1)
    print('这是第%s个进程'%i)
    
if __name__ == '__main__':
    ll = []
    for i in range(5):
        p = Process(target=write,args=(i,))
        p.start()
        # p.join()  
        # 如果加join,需要等到上一个进程执行完再执行下一个进程,串行执行,这是不对的
        ll.append(p)
    for i in ll:
        i.join()

高并发下的tcp服务端

import socket
from multiprocessing import Process

def tast(sock):
    while True:
        try:
            data = sock.recv(1024)
            print(data)
            if len(data) == 0 :
                break
            sock.send(data.upper())
        except Exception as e:
            print(e)
            break
    sock.close()

if __name__ == '__main__':
    server = socket.socket()
    server.bind(('127.0.0.1', 8080))
    server.listen(1)
    while True:
        sock, addr = server.accept()
        print(sock)
        print(addr)
        p = Process(target=tast,args=(sock,))
        p.start()

    server.close()
    
# 只需要将之前的服务端拿来稍加修改即可,注意一定要在main下运行

进程锁

锁是保证一个进程执行结束后再进行下一个进程

from multiprocessing import Process,Lock
import os,time

def task(i, lock):
    lock.acquire()
    # 第一步:上锁,acquire函数
    print('第%s个进程,进程id:%s执行开始了' % (i, os.getpid()))
    time.sleep(1)
    print('第%s个进程,进程id:%s执行结束了' % (i, os.getpid()))
    lock.release()
    # 第二步:释放锁,release函数

if __name__ == '__main__':
    lock = Lock()
    # 实例化得到一把锁,五个进程共用这把锁
    for i in range(5):
        p = Process(target=task, args=(i, lock))
        p.start()
posted @ 2021-07-20 20:40  麋鹿的麋  阅读(43)  评论(0)    收藏  举报