线程进程四

创建多进程

  • windows:进程、线程
  • linux:进程、线程(做了进程通信的多进程实现的线程)
  • 1:进程之间内存彼此独立,有效率,耗内存,某个进程挂了其他进程不受影响
    • linux下多用进程,windows多用线程
      • 父子进程
      • 单个独立进程
  • multiprocessing:Process
    • 北极星:mult
  • 一个任务(工作函数)绑定在一个进程
  • current_process:当前进程
  • 一定要把多进程的放在main

p1 = Process(target=func,name=,args=(),kwargs={})

p1.start() #开启进程

p1.join() #回收进程

p1.name #获取进程名字

p1.pid 获取进程ID之

p1.terminate 直接终止进程

p1.is_alive() 返回进程的存活状态 True/False

p1.exitcode 0代表进程死亡 None代表进程运行

p1.ident 和pid类似


僵尸进程
  • '''
    	如果父进程没有对子进程合理回收
    		父进程没有在子进程工作结束之后立即回收
    		PCB控制块 PID  僵尸进程
    	子进程结束 ,父进程存活
    '''
    from multiprocessing import Process,current_process
    from time import sleep
    
    def work():
    	print('子进程开始了')
    	print('PID:%s' % current_process().pid )
    	print('子进程结束了')
    
    def main():
    	p = Process(target=work)
    	p.start() #父进程开启了子进程
    	#p.join() #回收子进程
    	#父进程退出了
    	sleep(10) #退出
    	#p.join()
    
    if __name__ == '__main__':
    	main()
    

孤儿进程
  • # Python代码中如果在父进程没有明确写出join回收子进程
    # 在父进程结束之后,父进程回自动帮助回收
    kill -9 pid
    强制杀死
    

多进程通信

Python中任何普通的基础数据类型,都不可以在多进程下通信

  • Queue(size):共享队列,阻塞的行为
    • 满了不能放:q.put(block=True)
    • 空了不能取:q.get(block=True)
    • 默认为阻塞行为拿取/存放
    • 当修改了拿取的方式为非阻塞,那么数据在取不到或者立即放不进去的时候会直接报错
      • queue.Full 满了
      • queue.Empty 空的
    • q.empty()
      • 判断队列是否为空
    • q.full()
      • 判断队列是否为满
    • q.qsize()
      • 返回队列数据个数
    • 生产者、消费者
    • 取出来的数据就取出来了。没了
  • Pipe:duplex=True,存储的都是pickle
    • 总有人要先开口
    • left,right = Pipe(duplex)
    • pickle = p.recv() 向管道这一侧取出来
    • p.send(pickle) 向管道另一侧去发
    • 管道在使用的时候,是有两端的,要注意使用顺序
    • pickle.dumps()
    • pickle.loads()
  • Event:状态通信
    • from multiprocessing import Event
    • e = Event() e:状态实例
    • e.set() #设置当前的实例状态为True
    • e.clear() #设置当前的实例状态为False
    • e.wait()
      • False:阻塞等待
      • True:向下执行
  • Array、Value(不常见):共享内存\
    • 同步

多进程同步

  • 多进程默认是并发行为,多个进程同时执行
  • 执行的顺序,以及何时执行完毕无法控制
    • 多个进程如果涉及到了通信,数据的有序性无法保证
    • 需要某些东西来控制进程之间执行的顺序,锁
    • 对于进程资源的控制
  • 并发没有了。效率低下。同步
  • Lock:一把锁
    • Lock.acquire() 拿着锁 通信证
      • 抢占锁,如果拿不到,阻塞等待
    • Lock.release() 放掉锁
      • 一定要记得在工作完毕之后释放锁。
  • Semaphore:多把锁,同时提供多把锁/通行证,保证可以有一定个数的进程保持并发
    • s = Semaphore(3)
    • s.acquire()
    • s.release()

死锁

同步:按序执行

异步:乱序,谁有机会谁来

IO密集:疯狂的网络操作,爬虫,文件操作,数据库操作

​ 线程,切换快,彼此共享内存

​ 一个人多个头,只能同时一个头思考问题,IO等待的时候,线程切换

CPU密集:疯狂的计算

​ Linux:进程,高效利用每一颗头

​ 多个人,多个头

进程池

实例 lock:锁

from multiprocessing import Process,current_process,Lock
import sys
from time import sleep
def work(l,):
	print('我们开启了')
	for var in range(1000):
		print('%s:%s' % (current_process().name,var))
		sys.stdout.flush()
	#-----------------------------------------------
	l.acquire() #抢占这个通信证/锁 阻塞等待拿到锁/通行证
	for var in range(10000):
		print('%s:%s' % (current_process().name,var))
		sys.stdout.flush() #并发变为同步
	l.release() #放掉通信证
def main(): 
	l1 = Lock() #通信证,持有者可进园游玩
	Process(target=work,name='a',args=(l1,)).start()
	Process(target=work,name='b',args=(l1,)).start()
	Process(target=work,name='c',args=(l1,)).start()
#MYSql 
if __name__ == '__main__':
	main()

实例 Semaphore:


from multiprocessing import Process,current_process,Semaphore
import sys
from time import sleep
from socket import socket

def work(s,):
	s.acquire() #抢占这个通信证/锁 阻塞等待拿到锁/通行证
	for var in range(10000):
		print('%s:%s' % (current_process().name,var))
		sys.stdout.flush() #并发变为同步
	s.release() #放掉通信证

def main():
	s = Semaphore(3) #通信证,持有者可进园游玩
	Process(target=work,name='a',args=(s,)).start()
	Process(target=work,name='b',args=(s,)).start()
	Process(target=work,name='c',args=(s,)).start()
	Process(target=work,name='d',args=(s,)).start()
	Process(target=work,name='e',args=(s,)).start()
	Process(target=work,name='f',args=(s,)).start()

if __name__ == '__main__':
	main()

实例 event 1

from multiprocessing import Event,Process
from time import sleep
import sys
def work_a(e):
	print('这是a进程开启了')
	sys.stdout.flush()
	for var in range(10):
		sleep(1)
		print('...')
		sys.stdout.flush()
		if var == 5:
			e.set() #设置通信状态为True
		elif var == 8:
			e.clear()
#a->5
#b->
def work_b(e):
	for var in range(5):
		sleep(1)
		e.wait() #阻塞
		print('这是b进程开启了')
		sys.stdout.flush()

def main():
	e = Event() #True/**False**
	a = Process(target=work_a,args=(e,))
	b = Process(target=work_b,args=(e,))

	a.start()
	b.start()

	a.join()
	b.join()

if __name__ == '__main__':
	main()

实例 event 2

from multiprocessing import Event,Process
from time import sleep
import sys
def work(e):
	print('work进程已开启')
	sys.stdout.flush() #刷新输出缓冲区,立竿见影看到打印
	e.wait() #Sleep 可中断睡眠
	print('work进程正式开始工作')
	sys.stdout.flush()
	sys.stdout.flush()
	for var in range(10):
		pass
def main():
	print('主进程开启')
	e = Event()
	p = Process(target=work,args=(e,))
	p.start() #进程已经开启
	for var in range(3):
		print(var)
		sleep(1) #- e.wait()
	e.set() #信号变True
	p.join()

if __name__ == '__main__':
	main()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值