import os
import time
whileTrue:
time.sleep(0.5)print("hahaha")print("self", os.getpid())#获取自己的进程idprint("parent",os.getppid())#parent 获取父进程的id
互斥锁
# """# 当多个进程共享一个数据时,可能会造成数据错乱# 1.使用join 来让这些进程 串行 但是这将造成 无法并发 并且 进程执行任务的顺序就固定了# 2.使用锁 将需要共享的数据加锁 其他进程在访问数据时 就必须等待当前进程使用完毕## 锁的本质 就是一个bool类型的数据 在执行代码前 会先判断 这个值# 注意 在使用锁时 必须保证锁是同一个## 互斥锁# 互相排斥的锁## """#from multiprocessing import Process,Lock
import random
import time
deftask1(lock):
lock.acquire()# 是一个阻塞的函数 会等到别的进程释放锁才能继续执行
lock.acquire()print("1my name is:bgon")
time.sleep(random.randint(1,2))print("1my age is:78")
time.sleep(random.randint(1,2))print("1my sex is:femal")
lock.release()deftask2(lock):
lock.acquire()print("2my name is:blex")
time.sleep(random.randint(1,2))print("2my age is:68")
time.sleep(random.randint(1,2))print("2my sex is:femal")
lock.release()deftask3(lock):pass# 锁的实现原理 伪代码# l = False# def task3(lock):# global l# if l == False:# l = True# print("3my name is:常威")# time.sleep(random.randint(1, 2))# print("3my age is:68")# time.sleep(random.randint(1, 2))# print("3my sex is:femal")# l = Falseif __name__ =='__main__':
lock = Lock()
p1 = Process(target=task1,args=(lock,))
p1.start()# p1.join()
p2 = Process(target=task2,args=(lock,))
p2.start()# p2.join()
p3 = Process(target=task3,args=(lock,))
p3.start()# p3.join()## # 多个任务在共享一个数据时# # 串行效率低 但是不会出问题# # 并发效率高 但是数据可能错乱#### from multiprocessing import Lock,RLock,Process## lock = Lock()## lock.acquire()# print("haha ")# lock.acquire()# print('test')# lock.release()# RLock 表示可重入锁 特点是 可以多次执行acquire# Rlock 在执行多次acquire时 和普通Lock没有任何区别# 如果在多进程中使用Rlock 并且一个进程a 执行了多次acquire# 其他进程b要想获得这个锁 需要进程a 把锁解开 并且锁了几次就要解几次# 普通锁如果多次执行acquire将会锁死## lock = RLock()# lock.acquire()# lock.acquire()# print("哈哈")# lock.release()# import time# def task(i,lock):# lock.acquire()# lock.acquire()# print(i)# time.sleep(3)# lock.release()# lock.release()# #第一个过来 睡一秒 第二个过来了 睡一秒 第一个打印1 第二个打印2## if __name__ == '__main__':# lock = RLock()# p1 = Process(target=task,args=(1,lock))# p1.start()## p2 = Process(target=task, args=(2,lock))# p2.start()
开启进程的两种方式
from multiprocessing import Process
import os
#deftask(name):print(name)print("self",os.getpid())#66039print("parent", os.getppid())#66038print("task run")# windows创建子进程时 子进程会将父进程的代码加载一遍 导致重复创建子进程# 所以一定要将 创建子进程的代码放到main的下面if __name__ =='__main__':print("self", os.getpid())#66038print("parent", os.getppid())#36520
p = Process(target=task, name="这是子进程!",kwargs={"name":"bgon"})# 创建一个表示进程的对象 但并不是真正的创建进程
p.start()# 给操作系统发送通知 要求操作系统开启进程# 创建进程的第二种方式 继承Process 覆盖run方法# 在子进程启动以后会自动执行run方法# 其优势是 可以自定义 进程的属性和行为 来完成一些额外任务 例如下载# class MyProcess(Process):## def __init__(self,url):# self.url = url# super().__init__()## # 子类中的方法 只有run会被自动执行# def run(self):# print("下载文件...." , self.url)# print(" run run run!")## def task(self):# pass## def task():# print(123)# if __name__ == '__main__':# p = MyProcess("www.baidu.com/xx.mp4")# p.start()
进程间内存相互独立
from multiprocessing import Process
import time
a =1000000000000deftask():global a
print(id(a))
a =0print("子进程的",a)if __name__ =='__main__':print(id(a))
p = Process(target=task)
p.start()# 给操作系统发送请求后 代码继续往下运行 至于子进程 什么时候创建 什么是执行 都跟当前进程没关系
time.sleep(1)print("自己的",a)# 子进程中的数据修改 不会影响父进程
互斥锁的使用场景_抢票
import json
from multiprocessing import Process,Lock
import time
import random
"""
join和锁的区别
1.join中顺序是固定的 不公平
2.join是完全串行 而 锁可以使部分代码串行 其他代码还是并发
"""# 查看剩余票数defcheck_ticket(usr):
time.sleep(random.randint(1,3))withopen("ticket.json","r",encoding="utf-8")as f:
dic = json.loads(f.read())print("%s查看 剩余票数:%s"%(usr,dic.get('count')))defbuy_ticket(usr):withopen("ticket.json","r",encoding="utf-8")as f:
dic = json.load(f)if dic.get('count')>0:
time.sleep(random.randint(1,3))
dic["count"]-=1withopen("ticket.json","w", encoding="utf-8")as f2:
json.dump(dic,f2)print("%s 购票成功!"% usr)else:print('剩余票:',dic.get('count'))print('Not Found of tiket!')deftask(usr,lock):
check_ticket(usr)# time.sleep(1)
lock.acquire()
buy_ticket(usr)
lock.release()if __name__ =='__main__':
lock = Lock()for i inrange(10):
p = Process(target=task,args=("用户%s"% i,lock))
p.start()#p.join() # 只有第一个整个必须完毕 别人才能买 这是不公平的
父进程等待子进程结束
import time
from multiprocessing import Process
# def task():# print("上传文件....")# time.sleep(3)# print("上传结束...")### # [进程1,进程2,进程3]## if __name__ == '__main__':# p = Process(target=task)# p.start()## p.join() # 本质上 是提高了子进程优先级 当CPU在切换时 会优先切子进程## print("上传文件成功!")deftask(num):print("我是%s号 进程"% num)# time.sleep(1)print("=========")if __name__ =='__main__':
start_time = time.time()
ps =[]for i inrange(1,4):
p = Process(target=task,args=(i,))
p.start()print("----{}".format(i))# ps.append(p)for p in ps:
p.join()print(time.time()-start_time)print("over")
process 常用属性
from multiprocessing import Process
import time
deftask():# time.sleep(3)print("执行完毕!")if __name__ =='__main__':
p = Process(target=task, name="alex")
p.start()print(p.name)## # time.sleep(1)# print(p.is_alive())# #
p.terminate()# #print(p.is_alive())# # print(p.pid)# p.terminate() # 终止这个进程# print(p.pid)# print(p.is_alive())# p.daemon # 守护进程
"""
IPC 进程间通讯
由于进程之间内存是相互独立的 所以需要对应积极而方案 能够使得进程之间可以相互传递数据
1.使用共享文件,多个进程同时读写同一个文件
IO速度慢,传输数据大小不受限制
2.管道 是基于内存的,速度快,但是是单向的 用起来麻烦(了解)
3.申请共享内存空间,多个进程可以共享这个内存区域(重点)
速度快但是 数据量不能太大
"""from multiprocessing import Manager,Process
## def task(m):## print(m["num"])## if __name__ == '__main__':# # 开启了一个Manager# with Manager() as m:# m["num"] = 100 # 在这个空间中存储了一个num## for i in range(20):# p = Process(target=task,args=(m,))# p.start()##from multiprocessing import Manager,Process,Lock
defwork(d):# with lock:
d['count']-=1if __name__ =='__main__':with Manager()as m:
dic=m.dict({'count':100})#创建一个共享的字典
p_l=[]for i inrange(100):
p=Process(target=work,args=(dic,))
p_l.append(p)
p.start()for p in p_l:
p.join()print(dic)
僵尸进程
import time
from multiprocessing import Process
deftask1():print("子进程 run")if __name__ =='__main__':for i inrange(10):
p = Process(target=task1)
p.start()
time.sleep(100000)