开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第10天,点击查看活动详情
互斥锁
进程与进程之间的数据是不共享 , 可以使用文件共享数据实现进行之间的通信。当数据共享就会有竞争,竞争带来的问题就是数据错乱。
from multiprocessing import Process
import time
import json
def search(name):
time.sleep(1)
dic = json.load(open('db.txt' , 'r' , encoding='utf-8'))
print(f'{name}正在查看票源 , 当前剩余票数为{dic["count"]}')
def get(name):
dic = json.load(open('db.txt', 'r', encoding='utf-8'))
if dic["count"] > 0:
dic["count"] -= 1
time.sleep(2)
json.dump(dic , open('db.txt', 'w', encoding='utf-8'))
print(f'{name}购票成功')
def func(name):
search(name)
get(name)
if __name__ == '__main__':
for i in range(1 , 6):
p = Process(target=func , args=(f'Tom{i}号',))
p.start()
互斥锁:就是多个进程在访问同一个资源,加上互斥锁把并发成串行,可以保证数据的安全不会错乱;但是效率比较低。
加锁处理:以牺牲效率的情况 ,来保证数据的安全
from multiprocessing import Process , Lock
import time
import json
def search(name):
time.sleep(1)
dic = json.load(open('db.txt' , 'r' , encoding='utf-8'))
print(f'{name}正在查看票源 , 当前剩余票数为{dic["count"]}')
def get(name):
dic = json.load(open('db.txt', 'r', encoding='utf-8'))
if dic["count"] > 0:
dic["count"] -= 1
time.sleep(2)
json.dump(dic , open('db.txt', 'w', encoding='utf-8'))
print(f'{name}购票成功')
else:
print(f'{name}购票不成功')
def func(name , l):
search(name)
# 加锁
l.acquire()
get(name)
# 解锁
l.release()
if __name__ == '__main__':
# 创建锁
l = Lock()
for i in range(1 , 6):
p = Process(target=func , args=(f'Tom{i}号',l))
p.start()
from multiprocessing import Process , Lock
import time
import json
def search(name):
time.sleep(1)
dic = json.load(open('db.txt' , 'r' , encoding='utf-8'))
print(f'{name}正在查看票源 , 当前剩余票数为{dic["count"]}')
def get(name):
dic = json.load(open('db.txt', 'r', encoding='utf-8'))
if dic["count"] > 0:
dic["count"] -= 1
time.sleep(2)
json.dump(dic , open('db.txt', 'w', encoding='utf-8'))
print(f'{name}购票成功')
else:
print(f'{name}购票不成功')
def func(name , l):
search(name)
# 加锁
l.acquire()
get(name)
# 解锁
l.release()
if __name__ == '__main__':
# 创建锁
l = Lock()
for i in range(1 , 6):
p = Process(target=func , args=(f'Tom{i}号',l))
p.start()
p.join()
信号量
信号量也是一把锁
互斥锁是同一时间是只有一个任务能抢到锁
信号量同一时间可以有多个任务拿到锁
from multiprocessing import Process , Semaphore
import time
def black_room(name,s):
s.acquire()
print(f'{name}猥琐的溜进小黑屋')
time.sleep(3)
print(f'{name}惊恐的跑出房间')
s.release()
if __name__ == '__main__':
# 设置信号量 , 设置有多少个锁
s = Semaphore(3)
for i in range(10):
p = Process(target=black_room , args=(f'张三{i}号',s))
p.start()
进程通信
进程通信:消息队列
消息队列的使用:在内存中建立队列模型 , 进程通过队列将消息存入 , 或者从队列取出完成进程通信
from multiprocessing import Queue , Process
import time
def write(q):
# 将数据写入到queue消息队列中
ls = ['武则天','孙悟空','李白','孙尚香','亚瑟','鲁班']
for i in ls:
q.put(i)
print(f'queue获取到值:{i}')
time.sleep(2)
def read(q):
# 从消息队列中获取数据
while True:
# 判断消息队列总消息是否为空
if not q.empty():
value = q.get(True)
print(f'从消息队列中获取到值:{value}')
time.sleep(3)
else:
break
if __name__ == '__main__':
q = Queue()
w = Process(target=write,args=(q , ))
r = Process(target=read , args=(q,))
w.start()
w.join()
r.start()
r.join()
print('数据读取完毕')
线程
线程是资源分配单位,每一个进程中至少都会有一个线程,这个线程默认为主线程。
每个程序启动都默认有一个主线程 ,其他都是个我们自己创建的子线程
from threading import Thread
def work(name):
print(f'{name}在种田')
if __name__ == '__main__':
t = Thread(target=work , args=('阿宸',))
t.start()
在多个线程中 , 线程之间的数据是共享的
from threading import Thread
age = 20
def work(name):
global age
age = 24
print(f'{name}高龄{age} , 还在种田')
if __name__ == '__main__':
t = Thread(target=work , args=('阿宸',))
t.start()
print(age)
进程类
from multiprocessing import Process
import time
class MyProcess(Process):
def __init__(self,name):
super().__init__()
self.name = name
def eat(self , name):
for i in range(5):
print(f'{name}在吃第{i}碗鸡汤')
time.sleep(1)
# 自定义的进程类中 , 所有的任务需要到run方法中调用
def run(self):
print('开启进程任务')
self.eat(self.name)
print('结束进程任务')
if __name__ == '__main__':
p = MyProcess('阿宸')
p.start()
线程类
from threading import Thread
class MyThread(Thread):
def __init__(self):
super().__init__()
def read(self):
for i in range(5):
print('感谢大家收看 , 感谢大家收听 , 讲的不好请大家见谅')
print('各位身体倍棒')
print('各位晚安 , 好梦')
def run(self):
self.read()
if __name__ == '__main__':
t = MyThread()
t.start()