进程的互斥锁和消息队列

守护进程

from multiprocessing import Process
import time
​
def eat(name):
    for i in range(5):
        print(f'{name}在吃第{i}碗鸡汤')
        time.sleep(1)
​
if __name__ == '__main__':
​
    p = Process(target=eat , args=('小奕',))
    # daemon 当主进程结束的时候 , 也立刻结束掉子进程的程序
    p.daemon = True
    p.start()
    time.sleep(3)
    print('进程结束')

互斥锁

进程与进程之间的数据是不共享 , 可以使用文件共享数据实现进行之间的通信。当数据共享就会有竞争,竞争带来的问题就是数据错乱。

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 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('数据读取完毕')

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
进程条件变量和互斥的实现稍微复杂一些,需要使用操作系统提供的特定机制来实现进程间的通信和同步。以下是一种可能的实现方式: 1. 使用共享内存:创建一个共享内存区域,用于存储条件变量和互斥的状态信息。这个共享内存区域可以被多个进程共享访问。 2. 使用信号量:为了确保多个进程之间能够正确地访问共享内存区域,可以使用信号量来实现互斥访问。例如,可以使用一个二进制信号量来控制对共享内存的互斥访问。 3. 实现条件变量:在共享内存中创建一个条件变量结构体,它包含一个条件变量的状态和等待队列。当一个进程需要等待某个条件时,它可以将自己加入条件变量的等待队列中,并释放互斥。当条件满足时,其他进程可以通过发送信号唤醒等待队列中的进程。 4. 实现互斥:在共享内存中创建一个互斥结构体,它包含一个状态和当前持有进程标识符。当一个进程需要获取互斥时,它可以检查状态并将自己的进程标识符设置为持有进程标识符。如果已经被其他进程持有,则该进程需要等待。 通过这种方式,多个进程可以通过共享内存和信号量来实现条件变量和互斥的跨进程访问和同步。但是需要注意的是,这种实现方式需要考虑并发访问的竞争条件和死等问题,并使用合适的同步机制来解决。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值