day31 进程和其他方法,锁,队列
1.进程的其他方法:
首先引入模块:
import os
from multiprocessing import Process
p = Process(target=f,)
进程的id: p.pid 或者os.getpid 或者os.getppid
进程的名字: p.name
查看进程是否活着: p.is_alive #返回一个ture或者false
p.terminate 给操作系统发送一个结束进程的信号
import time
import os
from multiprocessing import Process
# def f1():
# print('子进程的pid',os.getpid())
# print('子进程的父进程的pid',os.getppid())
# print('aaa')
#
# def f2():
# print('bbb')
#
#
# if __name__ == '__main__':
#
# p1 = Process(target=f1,name='宝宝1')
# p2 = Process(target=f2,)
# p1.start()
# p2.start()
# print(p1.name)
# print('子进程的pid',p1.pid)
# print('父进程的id',os.getpid())
#进程的其他方法
def f1():
time.sleep(5)
print('子进程1号')
if __name__ == '__main__':
p = Process(target=f1,)
p.start()
print(p.is_alive()) #判断子进程是否还活着,是否还在运行
p.terminate() #给操作系统发送一个结束进程的信号
time.sleep(0.5)
print(p.is_alive())
2.验证进程之间是空间隔离的: 局部引入全局变量,在局部进行变量的重新赋值,查看全局变量是否被更改,如果没有更改,证明进程之间是空间隔离的,否则进程不是空间隔离的.
from multiprocessing import Process
num = 100
def f1():
global num
num= 3
print('子进程中的num',num)
print(">>>>>>>",num)
if __name__ == '__main__':
p=Process(target=f1,)
p.start()
p.join() ##等到子进程结束之后,主进程才能关闭
print('主进程中的num',num)
# >>>>>>> 100
# >>>>>>> 100
# 子进程中的num 3
# 主进程中的num 100
3.守护进程
p.deamon = True 守护进程,必须写在start之前,主进程的代码运行完成,设置为守护进程的子进程会随之结束
import time
from multiprocessing import Process
def f1():
time.sleep(3)
print('xxx')
def f2():
time.sleep(5)
print('普通子进程的代码')
if __name__ == '__main__':
p = Process(target=f1,)
p.daemon =True #将该进程设置为守护进程,必须写在start之前,意思是如果我的主进程代码运行结束了,你这子进程不管运行到什么地方,都直接结束
p.start()
#开启一个不同的子进程来验证一下守护进程的结束只和主进程的代码运行结束有关系,而整个程序的结束需要主进程的子进程的代码都运行结束才结束
p2 = Process(target=f2,)
p2.start()
#等待2号普通进程的结束,才继续执行写面主进程中的代码
# p2.join()
#守护进程会跟随父进程的代码结束,就结束
print('主进程结束')
4.进程锁(同步锁/互斥锁)
锁:保证数据的安全,但是牺牲了效率,枷锁的这段代码变成了(同步)串行执行的状态,又叫同步锁/互斥锁(重点)
a.第一种写法
loc =Lock()
loc.acquire()
需要锁的代码
loc.release()
b.第二种写法
with loc:
需要锁的代码
# 互斥锁/进程锁/同步锁
# import json
import time
from multiprocessing import Process,Lock
def show_t(i):
with open('ticket','r',encoding='utf-8') as f:
ticket_data = f.read()
# print(ticket_data)
t_data = eval(ticket_data)
# print(t_data,type(t_data))
print('%s查询剩余票数为%s'%(i,t_data['count']))
def get_t(i,l1):
l1.acquire()
with open('ticket', 'r', encoding='utf-8') as f:
ticket_data = f.read()
# print(ticket_data)
t_data = eval(ticket_data)
# print(t_data,type(t_data))
# print('%s查询剩余票数为%s' % (i, t_data['count']))
if t_data['count'] > 0:
t_data['count'] -= 1
print('%s抢票成功'%i)
time.sleep(0.2)
with open('ticket', 'w') as f:
f.write(str(t_data))
else:
print('没票了!!!')
l1.release()
if __name__ == '__main__':
l1 = Lock()
for i in range(10):
p1 = Process(target=show_t,args=(i,))
p1.start()
for i in range(10):
p2 = Process(target=get_t,args=(i,l1) )
p2.start()
5.数据的共享
Manager() 数据共享,也需要在导入进程模块使用
import time
from multiprocessing import Process,Manager,Lock
def f1(m_d,l2):
# m_d['num'] -= 1 #
with l2:
# l2.acquire()
tmp = m_d['num']
tmp -= 1
time.sleep(0.1)
m_d['num'] = tmp
# l2.release()
if __name__ == '__main__':
m = Manager()
l2 = Lock()
m_d = m.dict({'num':100})
p_list = []
for i in range(10):
p = Process(target=f1,args=(m_d,l2))
p.start()
p_list.append(p)
[pp.join() for pp in p_list]
print(m_d['num'])
6队列(重点) Queue()
q = Queue(10)
q.put() 放数据
q.get() 取数据
q.qsize() 返回的是当前队列中内容的长度
q.put_nowait() 不等待,但是报错
q.get_nowait() 不等待,但是报错
q.full() 因为这个东西不可靠,满了返回一个True,不满返回一个False
q.empty() 因为这个东西不可靠,空了返回一个True,不空返
from multiprocessing import Process,Queue
q = Queue(3) #创建一个队列对象,队列长度为3,先进先出
q.put(1)
# print('>>>>>',q.qsize()) #返回当前队列的内容长度
print(q.full())
q.put(2)
# print('>>>>>',q.qsize())
q.put(3)
print(q.full()) #q.full()了解,因为这个东西不可靠,满了返回一个True,不满返回一个False
# print('sss')
# q.put(4) #放入数据的时候,如果队列满了了,程序会在你put操作的地方阻塞
# try:
# q.put_nowait(4) #不阻塞程序,但是会报错queue.Full,可以通过捕获异常来进行其他的操作
# except:
# print('队列满了,玩别的去吧')
# print('xxx')
print(q.get())
print(q.get())
print(q.get())
print('是不是空了呀:',q.empty()) #q.empty()了解,因为这个东西不可靠,空了返回一个True,不空返
# q.put(4)
# print('是不是空了呀:',q.empty()) #True或者False,因为q在put数据的时候,有一个细微的延迟
# 回一个False
# print(q.get()) #如果队列空了,程序会在这个地方卡主,也就是阻塞程序
try:
q.get_nowait() #queue.Empty
except:
print('队列空了,搞得别的事情')
print('拿多啦')
7.JoinableQueue
task_done() 给队列返回一个任务处理完毕的信号
join() 等待放入队列的人物全部执行完毕,也就是等待task_done()的信号数量等于放入队列中的所有任务的数量,不然会阻塞
import time
from multiprocessing import Process,Queue,JoinableQueue
#生产者
def producer(q):
for i in range(10):
time.sleep(0.2)
s = '大包子%s号'%i
print(s+'新鲜出炉,拿去用')
q.put(s)
q.join() #就等着task_done()信号的数量,和我put进去的数量相同时,才继续执行
print('所有的任务都被处理了,继续潜行吧骚年们')
def consumer(q):
while 1:
time.sleep(0.5)
baozi = q.get()
print(baozi+'被吃了')
q.task_done() #给队列发送一个取出的这个任务已经处理完毕的信号
if __name__ == '__main__':
# q = Queue(30)
q = JoinableQueue(30) #同样是一个长度为30的队列
pro_p = Process(target=producer,args=(q,))
con_p = Process(target=consumer,args=(q,))
pro_p.start()
con_p.daemon = True
con_p.start()
pro_p.join()
print('主进程结束')
1.进程的其他方法:
首先引入模块:
import os
from multiprocessing import Process
p = Process(target=f,)
进程的id: p.pid 或者os.getpid 或者os.getppid
进程的名字: p.name
查看进程是否活着: p.is_alive #返回一个ture或者false
p.terminate 给操作系统发送一个结束进程的信号
import time
import os
from multiprocessing import Process
# def f1():
# print('子进程的pid',os.getpid())
# print('子进程的父进程的pid',os.getppid())
# print('aaa')
#
# def f2():
# print('bbb')
#
#
# if __name__ == '__main__':
#
# p1 = Process(target=f1,name='宝宝1')
# p2 = Process(target=f2,)
# p1.start()
# p2.start()
# print(p1.name)
# print('子进程的pid',p1.pid)
# print('父进程的id',os.getpid())
#进程的其他方法
def f1():
time.sleep(5)
print('子进程1号')
if __name__ == '__main__':
p = Process(target=f1,)
p.start()
print(p.is_alive()) #判断子进程是否还活着,是否还在运行
p.terminate() #给操作系统发送一个结束进程的信号
time.sleep(0.5)
print(p.is_alive())
2.验证进程之间是空间隔离的: 局部引入全局变量,在局部进行变量的重新赋值,查看全局变量是否被更改,如果没有更改,证明进程之间是空间隔离的,否则进程不是空间隔离的.
from multiprocessing import Process
num = 100
def f1():
global num
num= 3
print('子进程中的num',num)
print(">>>>>>>",num)
if __name__ == '__main__':
p=Process(target=f1,)
p.start()
p.join() ##等到子进程结束之后,主进程才能关闭
print('主进程中的num',num)
# >>>>>>> 100
# >>>>>>> 100
# 子进程中的num 3
# 主进程中的num 100
3.守护进程
p.deamon = True 守护进程,必须写在start之前,主进程的代码运行完成,设置为守护进程的子进程会随之结束
import time
from multiprocessing import Process
def f1():
time.sleep(3)
print('xxx')
def f2():
time.sleep(5)
print('普通子进程的代码')
if __name__ == '__main__':
p = Process(target=f1,)
p.daemon =True #将该进程设置为守护进程,必须写在start之前,意思是如果我的主进程代码运行结束了,你这子进程不管运行到什么地方,都直接结束
p.start()
#开启一个不同的子进程来验证一下守护进程的结束只和主进程的代码运行结束有关系,而整个程序的结束需要主进程的子进程的代码都运行结束才结束
p2 = Process(target=f2,)
p2.start()
#等待2号普通进程的结束,才继续执行写面主进程中的代码
# p2.join()
#守护进程会跟随父进程的代码结束,就结束
print('主进程结束')
4.进程锁(同步锁/互斥锁)
锁:保证数据的安全,但是牺牲了效率,枷锁的这段代码变成了(同步)串行执行的状态,又叫同步锁/互斥锁(重点)
a.第一种写法
loc =Lock()
loc.acquire()
需要锁的代码
loc.release()
b.第二种写法
with loc:
需要锁的代码
# 互斥锁/进程锁/同步锁
# import json
import time
from multiprocessing import Process,Lock
def show_t(i):
with open('ticket','r',encoding='utf-8') as f:
ticket_data = f.read()
# print(ticket_data)
t_data = eval(ticket_data)
# print(t_data,type(t_data))
print('%s查询剩余票数为%s'%(i,t_data['count']))
def get_t(i,l1):
l1.acquire()
with open('ticket', 'r', encoding='utf-8') as f:
ticket_data = f.read()
# print(ticket_data)
t_data = eval(ticket_data)
# print(t_data,type(t_data))
# print('%s查询剩余票数为%s' % (i, t_data['count']))
if t_data['count'] > 0:
t_data['count'] -= 1
print('%s抢票成功'%i)
time.sleep(0.2)
with open('ticket', 'w') as f:
f.write(str(t_data))
else:
print('没票了!!!')
l1.release()
if __name__ == '__main__':
l1 = Lock()
for i in range(10):
p1 = Process(target=show_t,args=(i,))
p1.start()
for i in range(10):
p2 = Process(target=get_t,args=(i,l1) )
p2.start()
5.数据的共享
Manager() 数据共享,也需要在导入进程模块使用
import time
from multiprocessing import Process,Manager,Lock
def f1(m_d,l2):
# m_d['num'] -= 1 #
with l2:
# l2.acquire()
tmp = m_d['num']
tmp -= 1
time.sleep(0.1)
m_d['num'] = tmp
# l2.release()
if __name__ == '__main__':
m = Manager()
l2 = Lock()
m_d = m.dict({'num':100})
p_list = []
for i in range(10):
p = Process(target=f1,args=(m_d,l2))
p.start()
p_list.append(p)
[pp.join() for pp in p_list]
print(m_d['num'])
6队列(重点) Queue()
q = Queue(10)
q.put() 放数据
q.get() 取数据
q.qsize() 返回的是当前队列中内容的长度
q.put_nowait() 不等待,但是报错
q.get_nowait() 不等待,但是报错
q.full() 因为这个东西不可靠,满了返回一个True,不满返回一个False
q.empty() 因为这个东西不可靠,空了返回一个True,不空返
from multiprocessing import Process,Queue
q = Queue(3) #创建一个队列对象,队列长度为3,先进先出
q.put(1)
# print('>>>>>',q.qsize()) #返回当前队列的内容长度
print(q.full())
q.put(2)
# print('>>>>>',q.qsize())
q.put(3)
print(q.full()) #q.full()了解,因为这个东西不可靠,满了返回一个True,不满返回一个False
# print('sss')
# q.put(4) #放入数据的时候,如果队列满了了,程序会在你put操作的地方阻塞
# try:
# q.put_nowait(4) #不阻塞程序,但是会报错queue.Full,可以通过捕获异常来进行其他的操作
# except:
# print('队列满了,玩别的去吧')
# print('xxx')
print(q.get())
print(q.get())
print(q.get())
print('是不是空了呀:',q.empty()) #q.empty()了解,因为这个东西不可靠,空了返回一个True,不空返
# q.put(4)
# print('是不是空了呀:',q.empty()) #True或者False,因为q在put数据的时候,有一个细微的延迟
# 回一个False
# print(q.get()) #如果队列空了,程序会在这个地方卡主,也就是阻塞程序
try:
q.get_nowait() #queue.Empty
except:
print('队列空了,搞得别的事情')
print('拿多啦')
7.JoinableQueue
task_done() 给队列返回一个任务处理完毕的信号
join() 等待放入队列的人物全部执行完毕,也就是等待task_done()的信号数量等于放入队列中的所有任务的数量,不然会阻塞
import time
from multiprocessing import Process,Queue,JoinableQueue
#生产者
def producer(q):
for i in range(10):
time.sleep(0.2)
s = '大包子%s号'%i
print(s+'新鲜出炉,拿去用')
q.put(s)
q.join() #就等着task_done()信号的数量,和我put进去的数量相同时,才继续执行
print('所有的任务都被处理了,继续潜行吧骚年们')
def consumer(q):
while 1:
time.sleep(0.5)
baozi = q.get()
print(baozi+'被吃了')
q.task_done() #给队列发送一个取出的这个任务已经处理完毕的信号
if __name__ == '__main__':
# q = Queue(30)
q = JoinableQueue(30) #同样是一个长度为30的队列
pro_p = Process(target=producer,args=(q,))
con_p = Process(target=consumer,args=(q,))
pro_p.start()
con_p.daemon = True
con_p.start()
pro_p.join()
print('主进程结束')