02:进程调度 --- 进程同步(进程锁)

1 进程调度算法(了解)

 

 

-先来先服务调度算法
-短作业优先调度算法
-时间片轮转法
-多级反馈队列

2 同步异步,阻塞非阻塞(了解)

 

 

1 同步调用:提交了以后,一直等待结果返回
2 异步调用:提交了以后,返回一个标志,等执行完成后,有消息通知
3 同步,异步:指的是消息通知机制

4  阻塞,非阻塞:程序在等待调用结果的状态
5 同步阻塞:打电话要买书,如果电话没挂,我也一直在等待,
6 同步非阻塞:打电话买书,电话没挂,我一边干别的事,一边听一下电话
7 异步阻塞:打电话买书,电话先挂掉,过一会老板会回回来(回调),老板给回电话的过程一直在等待
8 异步非阻塞:打电话买书,电话先挂掉,过一会老板会回回来(回调),老板给回电话的过程中,在干别的事

3 Process类的参数(重点)

 

 

from multiprocessing import Process
​
​
def task(name,age):
    print(name)
    print(age)
​
​
if __name__ == '__main__':
    # p=Process(target=task,args=['lqz',18])
    # p=Process(target=task,kwargs={'age':19,'name':'lqz'},name='process01')
    p=Process(target=task,kwargs={'age':19,'name':'lqz'})
    p2=Process(target=task,kwargs={'age':19,'name':'lqz'})
    p.start()
    p2.start()
​
    print(p.name)
    print(p2.name)
    # target=None, 你要执行的任务,函数
    # name=None,  进程名
    # args=(),    以位置参数给任务(函数)传递参数
    # kwargs={}   以关键字的形式给任务(函数)传递参数

 

4 Process类的方法,属性(重点)

 

 


from multiprocessing import Process
import time
​
def task(name,age):
    time.sleep(10)
    print(name)
    print(age)
​
​
if __name__ == '__main__':
    p=Process(target=task,kwargs={'age':19,'name':'lqz'})
​
​
    p.start()  #启动进程,必须调用start
    # p.run()    # 实际进程在执行的时候,执行的是run方法,但是调用run不会开进程,后面我们另一种开启进程的方案使用到它
# p.join()    # 等待子进程执行完成
​
​
    print(p.is_alive())   #True
​
    p.terminate() # 杀死p这个进程,通知操作系统去杀死该进程
    time.sleep(0.1)
​
    print(p.is_alive())  #可能还是True
    print('ssss')
​
    print(p.is_alive())  #就是False
print(p)
​
    
掌握↓↓↓ 
'''
p.start()  #启动进程,必须调用start
p.run()    # 实际进程在执行的时候,执行的是run方法,但是调用run不会开进程,后面我们另一种开启进程的方案使用到它
p.join()    # 等待子进程执行完成
p.terminate() # 杀死p这个进程,通知操作系统去杀死该进程,并不是立即结束
p.is_alive() #进程是否还存活
'''

 

 

2.1 属性

from multiprocessing import Process
import time
​
def task(name,age):
    time.sleep(10)
    print(name)
    print(age)
​
​
if __name__ == '__main__':
    p=Process(target=task,kwargs={'age':19,'name':'lqz'})
    # p.start()
    # print(p.name) # 进程名字
    # p.daemon=True  #主进程结束,子进程也结束,必须在start之前调用
    p.start()
    print(p.pid)  # 进程id号
    time.sleep(10)
​
掌握↓↓↓ 
'''
print(p.name) # 进程名字
print(p.pid)  # 进程id号
p.daemon=True  #主进程结束,子进程也结束,必须在start之前调用
'''

 

主进程和子进程的进程号

from multiprocessing import Process
import time
import os
def task(name,age):
    # 如果在任务中取出进程id号,需要使用os模块
    print('当前进程(子进程)id号是:',os.getpid()) #当前进程id号
    print('当前进程父进程的id号是:',os.getppid()) # 当前进程父进程的id号
    time.sleep(10)
​
    print(name)
    print(age)
​
​
if __name__ == '__main__':
    p=Process(target=task,kwargs={'age':19,'name':'lqz'})
    p.start()
    print('p这个进程的id号是:',p.pid)  # 进程id号
    print('当前进程id(主进程)号是:', os.getpid())  # 当前进程id号
    print('当前进程父进程(pycharm)的id号是:', os.getppid())  # 当前进程父进程的id号
    time.sleep(10)
​
掌握↓↓↓ 
'''
如果有p对象,就是用p.pid获取进程id号
如果没有p对象,就是用os模块的
os.getpid() #当前进程id号
os.getppid() #父进程id号
'''

 

同时开启多个进程


from multiprocessing import Process
import time
import os
# def task(name,age):
#     time.sleep(10)
#     print(name)
#     print(age)
# def task1():
#     time.sleep(2)
#     print("我是task1")
#
#
# if __name__ == '__main__':
#     p=Process(target=task,kwargs={'age':19,'name':'lqz'})
#     p.start()
#
#     p1=Process(target=task1)
#     p1.start()
#
#     print('主进程')
import time
​
def task1(i):
    time.sleep(2)
    print("我是task1",i)
​
​
if __name__ == '__main__':
    ctime=time.time()
    ll=[]
    for i in range(5):
        p1=Process(target=task1,args=[i,])
        p1.start()
        p1.join()  #等待子进程执行完成
        # ll.append(p1)
# for p in ll:
    #     p.join()
    [p.join()for p in ll]
    print('主进程')
    print(time.time()-ctime)
    
​
掌握↓↓↓     
'''
开启多个进程
如果想等待多个进程同时执行完,先把进程开启完成,再统一join
'''

 

 

开启进程的另一种方案

### 通过继承Process类的方式来实现,重写run方法,run方法就是你要执行的任务,实例化得到对象,调用start方法开启进程
class MyProcess(Process):
    def __init__(self,name1,age):
        self.name1=name1
        self.age=age
        # 这个必须写
        super().__init__()
​
    def run(self) :
        time.sleep(2)
        print(self.name)
        print(self.name1)
        print(self.age)
​
if __name__ == '__main__':
    p=MyProcess('lqz',19)
    p.start() #调用p.start(),不要调用run
    print('主进程')

 

进程之间数据隔离

from multiprocessing import Process
import time
import os


def task():
    print('我是task')
    global n
    n=100
    print('子进程的:',n)



if __name__ == '__main__':
    # 在主进程中定义了一个n=10
    n=10

    ###如果这样写,n会被改掉
    # task()
    # print(n)

    ##如果这样写,n不会被改掉
    p=Process(target=task)
    p.start()
    print('主进程的:',n)

 

5 高并发的TCP服务端

 

 

import socket
from multiprocessing import Process




def talk(sock,addr):
    print('客户端连接成功',addr)
    while True:
        try:
            data = sock.recv(1024)
            if len(data) == 0:
                break
            print('从客户端收到了:', data)
            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', 81))
    server.listen(5)
    while True:
        print('等待客户端连接')
        sock, addr = server.accept()
        p=Process(target=talk,args=[sock,addr])
        p.start()
    server.close()
from multiprocessing import Process
import time
import os


def task():
    print('我是task')
    global n
    n=100
    print('子进程的:',n)



if __name__ == '__main__':
    # 在主进程中定义了一个n=10
    n=10

    ###如果这样写,n会被改掉
    # task()
    # print(n)

    ##如果这样写,n不会被改掉
    p=Process(target=task)
    p.start()
    print('主进程的:',n)

 

6 进程同步(进程锁)(次重点)

 

 

import time
## 不加锁

import json
from multiprocessing import Process,Lock


## 查询票余额
def check(i):
    with open('ticket', 'rt', encoding='utf-8') as f:
        res = json.load(f)
    print('%s:在查询票,票还剩%s张' % (i, res['count']))
    if res['count'] > 0:
        return True


## 抢票,票的余额减一

def buy(i):
    with open('ticket', 'rt', encoding='utf-8') as f:
        res = json.load(f)
    time.sleep(1)  # 模拟查票延迟
    if res['count'] > 0:
        print('%s现在要买了,票数还是大于0'%i)
        res['count'] -= 1
        time.sleep(2)  # 模拟买票延迟
        with open('ticket', 'wt', encoding='utf-8') as f1:
            json.dump(res, f1)
        print('%s这个人购票成功' % i)
    else:
        print('%s这个人购票失败,票不够了,买不了了' % i)


def task(i,lock):
    res = check(i)
    if res:
        lock.acquire()
        buy(i)
        lock.release()


##模拟10个人买票

if __name__ == '__main__':
    lock=Lock()
    for i in range(10):
        p = Process(target=task, args=[i,lock ])
        p.start()

 

总结

 

 

1 进程调度算法
	-先来先服务
    -短作业有限
    -时间片轮转
    -多级反馈队列
    
2 同步,异步;阻塞,非阻塞
	-同步和异步:指的是回调方式,如果有回调,就是异步,如果同步等待就是同步
    -阻塞,非阻塞:指等待消息结果时的状态,如果在等的过程中,干了别的事,就是非阻塞,如果一直等就是阻塞
3 进程类Process类,实例化的时候的参数:
	-target:要执行的任务
    -args:以位置形式给任务传值
    -kwargs:以关键字给任务传值
    -name:进程名字(如果不写,会有个默认名字)
    
4 进程对象的属性和方法
	-属性
    	-name
        -pid:进程id号,如果没有这个对象,需要借助os.getpid(),os.getppid()
        -daemon:守护进程,如果设置为True,主进程挂掉,这个进程也会挂掉,需要在p.start之前执行
    -方法:
    	-is_alive()  进程是否存活
        -terminate()  停止该进程
        -join()       等待子进程执行结束,主进程再继续执行
        -start()      子进程要执行,必须调用它
        -run()        真正的任务
        
5 开启进程的另一种方式(类的继承)
	写一个类,继承Process类
    重写run方法,就是你的任务
    实例化得到我们写的类,调用这个类对象的.start()
    
6 进程间数据是隔离的    
6 进程锁
	-多个进程操作同一个数据(文件中的数据,而不是内存中的数据:)
    -lock=Lock()
    -加锁:lock.acquire()
    -解锁:lock.release()




posted @ 2021-04-22 19:59  Jerry`  阅读(130)  评论(0编辑  收藏  举报