day 29 守护进程/互斥锁/IPC通信机制/生产者消费者模型

1守护进程

  基于并发是执行两个任务,主任务结束了,守护进程的副进程也是结束了。

  obj.daemon=True 就是把obj变成守护进程。副进程了。

  使用情况:开子进程是需要并发任务,使用守护,守护周期。是在主进程全都干完了,子进程没有必要存在了。

def task(name):
print('%s is running' % name)
time.sleep(3)

if __name__ == '__main__':
obj = Process(target=task, args=('egon',))
obj.daemon=True
obj.start() # 发送信号给操作系统
print('主')

2 互斥锁

  多个进程,抢占一个共享资源,不出现错乱的情况一定要排队。

  导入一个类lock()

  mutex=lock()

  lock.acqiure() 开始上锁,不能连续lock.acqiure()

  lock.release() 释放锁。互斥锁:

强调:必须是lock.acquire()一次,然后 lock.release()释放一次,才能继续lock.acquire(),不能连续的lock.acquire()

  

  互斥锁与join的区别

  一二者的原理都是一样,都是将并发变成串行,从而保证有序

  区别 join是按照认为指定的顺序执行。而互斥锁是所有的进程平等地竞争。谁先抢到谁执行

  区别二都是 互斥锁是可以添加任意的代码里面。可以让一部分代码串行,(修改共享数据的代码)json只能将代码整体串行

 

def task1(lock):
lock.acquire() #
print('task1:名字是egon')
time.sleep(random.randint(1,3))
print('task1:性别是male')
time.sleep(random.randint(1,3))
print('task1:年龄是18')
lock.release()

def task2(lock):
lock.acquire()
print('task2:名字是alex')
time.sleep(random.randint(1,3))
print('task2:性别是male')
time.sleep(random.randint(1,3))
print('task2:年龄是78')
lock.release()


def task3(lock):
lock.acquire()
print('task3:名字是lxx')
time.sleep(random.randint(1,3))
print('task3:性别是female')
time.sleep(random.randint(1,3))
print('task3:年龄是30')
lock.release()


if __name__ == '__main__':
p1=Process(target=task1,args=(mutex,))
p2=Process(target=task2,args=(mutex,))
p3=Process(target=task3,args=(mutex,))

# p1.start()
# p1.join()
# p2.start()
# p2.join()
# p3.start()
# p3.join()

p1.start()
p2.start()
p3.start()


iPC通信机制 Queue

  进程之间通信必须找到一种介质,该介质必须满足

  是所有进程共享的

  必须是内存空间

  附加,帮我们自己处理好锁的问题

队列和管道的区别

管道没有锁

队列是有锁

管道两头都是可以取存。

队列是一头存一头取。推荐队列

队列用来存成进程之间的沟通的消息,数据量不应该过大

maxisize的值超过内存限制就变得毫无意义

# 队列:
#1、共享的空间
#2、是内存空间
#3、自动帮我们处理好锁定问题
from multiprocessing import Process,Manager,Lock
import time

mutex=Lock()

def task(dic,lock):
lock.acquire()
temp=dic['num']
time.sleep(0.1)
dic['num']=temp-1
lock.release()

if __name__ == '__main__':
m=Manager()
dic=m.dict({'num':10})

l=[]
for i in range(10):
p=Process(target=task,args=(dic,mutex))
l.append(p)
p.start()

for p in l:
p.join()
print(dic)

 

生产者消费者模型,解决代码的思路,不受限与某个进程

该模型中包含两类重要的角色

1生产者:将负责造数据的生产者

2 消费者:接受生产者造出的数据。来做进一步的处理。该类人物被比喻成消费者

实现生产者消费者模型

1 生产者

2消费者

3队列

什么时候用该模型,

程序中出现明显的两类任务,一类任务是负责生产,另外一类任务是负责处理生产的数的。

用该模型的好处是,

好处之一是实现生产者与消费者解耦和,

平衡了生产力与消费力。就是即生产者可以一直不停地生产,消费者可以不停地处理,因为二者不再是直接沟通,而是通过队列沟通。


import time
import random
from multiprocessing import Process,Queue

def consumer(name,q):
while True:
res=q.get()
time.sleep(random.randint(1,3))
print('\033[46m消费者===》%s 吃了 %s\033[0m' %(name,res))


def producer(name,q,food):
for i in range(5):
time.sleep(random.randint(1,2))
res='%s%s' %(food,i)
q.put(res)
print('\033[45m生产者者===》%s 生产了 %s\033[0m' %(name,res))


if __name__ == '__main__':
#1、共享的盆
q=Queue()

#2、生产者们
p1=Process(target=producer,args=('egon',q,'包子'))
p2=Process(target=producer,args=('刘清政',q,'泔水'))
p3=Process(target=producer,args=('杨军',q,'米饭'))

#3、消费者们
c1=Process(target=consumer,args=('alex',q))
c2=Process(target=consumer,args=('梁书东',q))


p1.start()
p2.start()
p3.start()
c1.start()
c2.start()

转载于:https://www.cnblogs.com/seanliang/p/8944677.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个使用Java语言实现的生产者/消费者模型的完整代码,实现了同步和互斥操作: ```java import java.util.LinkedList; import java.util.Queue; import javax.swing.JFrame; import javax.swing.JTextArea; public class ProducerConsumer extends JFrame { private JTextArea output; // 用于显示输出信息的文本区域 private Queue<Integer> buffer; // 缓冲区队列 private final int BUFFER_SIZE = 5; // 缓冲区大小 private final Object lock = new Object(); // 用于同步的锁对象 public ProducerConsumer() { super("Producer/Consumer Demo"); output = new JTextArea(); add(output); setSize(300, 300); setVisible(true); buffer = new LinkedList<Integer>(); new Producer().start(); new Consumer().start(); } public static void main(String[] args) { new ProducerConsumer(); } // 生产者线程 private class Producer extends Thread { public void run() { int item; while (true) { synchronized (lock) { // 如果缓冲区已满,则等待 while (buffer.size() == BUFFER_SIZE) { try { lock.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } item = produceItem(); buffer.add(item); output.append("Produced item " + item + "\n"); // 唤醒等待的消费者线程 lock.notifyAll(); } // 生产完一个物品后随机休眠一段时间 try { Thread.sleep((int) (Math.random() * 3000)); } catch (InterruptedException e) { e.printStackTrace(); } } } // 生产一个物品 private int produceItem() { return (int) (Math.random() * 100); } } // 消费者线程 private class Consumer extends Thread { public void run() { int item; while (true) { synchronized (lock) { // 如果缓冲区为空,则等待 while (buffer.size() == 0) { try { lock.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } item = buffer.remove(); output.append("Consumed item " + item + "\n"); // 唤醒等待的生产者线程 lock.notifyAll(); } // 消费完一个物品后随机休眠一段时间 try { Thread.sleep((int) (Math.random() * 3000)); } catch (InterruptedException e) { e.printStackTrace(); } } } } } ``` 在此代码中,我们使用了一个JTextArea对象来显示输出信息。缓冲区队列使用了Java集合框架中提供的LinkedList类,而同步和互斥操作则使用了Java中的synchronized关键字和wait()/notifyAll()方法。在程序运行时,我们创建了一个生产者线程和一个消费者线程,它们在同一个缓冲区队列上进行操作。当缓冲区已满时,生产者线程将等待,直到消费者线程取走一个物品,唤醒生产者线程;当缓冲区为空时,消费者线程将等待,直到生产者线程放入一个物品,唤醒消费者线程。通过这种方式,我们实现了生产者/消费者模型中的同步和互斥操作。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值