进程 >> 互斥锁、队列与管道、生产者消费者模型

目录

  • 1.互斥锁
  • 2.队列与管道
  • 3.生产者消费者模型(Queue)
  • 4.生产者消费者模型(JoinableQueue)

1.互斥锁

  • 首先导入Lock模块
  • 实例化一把锁
  • 但是每次生成子进程的时候都会重新实例化一把锁,我们的目的是想让所有的子进程使用同一把锁,所以需要把锁传递给子进程在使用 锁名.acquire():开锁->所有子进程开始抢位置 锁名.release():关锁->位置排好了,开始执锁起来执行.
  • join与互斥锁的区别:join是把所有的子进程代码变为串行的,而互斥锁则可以规定那几行代码变为串行
from multiprocessing import Process,Lock
import time

def foo(user,lock_new):
    lock_new.acquire()
    print(f"{user}--1")
    time.sleep(1)
    print(f"{user}--2")
    time.sleep(1)
    print(f"{user}--3")
    lock_new.release()

if __name__ == '__main__':
    lock_new = Lock()
    for i in range(1,4):
        p = Process(target=foo, args=(i,lock_new))
        p.start()

2.队列与管道

  • 互斥锁是基于硬盘资源的
  • 队列和管道是基于内存的,multiprocessing模块提供了这个处理操作,也就是IPC,基于网络间进程通信的方式
  • 队列是管道和锁的结合
  • 队列需要遵守先进先出算法
  • 还有就是就算不控制队列大小,他之后也会往里面塞数据
  • 队列里面是放小数据的,不可以放类似视频的这种大数据
from multiprocessing import Queue

q = Queue(3)
q.put(1)
q.put(2)
q.put(3)
print(q.full())
print(q.get())
print(q.get())
print(q.get())
print(q.empty())

3.生产者消费者模型(Queue)

* 生产者消费者模型是根据队列来实现的
* 生产者把产生的消费者所需要的数据放入队列中,消费者再去队列中取出来
* 这一个知识点其实是队列的应用方式
from multiprocessing import Process, Queue

def producer(pro_name, q):  # 生产者
    for i in range(1,4):
        res = f"{pro_name}生产的第{i}个蛋"
        time.sleep(2)
        print(res)
        q.put(res)

def consumer(con_name, q):
    while True: # 必须得死循环,因为你不知道生产者会生产多少东西,这个时候进程间通讯就起到很重要的作用
        res = q.get()
        if res is None:
            break
        print(f"{con_name}吃{res}")

if __name__ == '__main__':
    q = Queue()
    p1 = Process(target=producer,args=("xc",q))
    c1 = Process(target=consumer,args=("wr",q))
    p1.start()
    c1.start()
    p1.join()
    q.put(None) # 在生产者结束生产之后,再传一个空值,因为消费者处于一直等待的状态,必须使用结束语句
    c1.join()
    print("打烊了")

4.生产者消费者模型(JoinableQueue)

from multiprocessing import Process,JoinableQueue
import time

def producer(pro_name, q):  # 生产者
    for i in range(3):
        print(f"{pro_name}做的第{i+1}个包子")
        res = f"{pro_name}做的第{i+1}个包子"
        q.put(res)
    # q.join() # 接受消费者取值的信号
def consumer(con_name, q):
    while True:
        res = q.get()
        print(f"{con_name}吃了{res}")
        q.task_done()  # 发送消费者取值的信号,消费者把管道里面的数据取完了之后,生产者里面的join才会结束运行
        # 这个其实就是这个数据要是接收完毕,就会给发送数据的一个消息,发送数据就可以执行完毕

if __name__ == '__main__':
    q = JoinableQueue() # 这个方法 也就是可以join的 (也就是等待包含task_done的语句数据接收完,而不是执行完的时候)
    p1 = Process(target=producer,args=('xc',q))
    p2 = Process(target=producer,args=('xxc',q))
    c1 = Process(target=consumer,args=('小狗',q))
    c1.daemon = True # 因为本身消费者语句虽然接收完数据了,但是还是再运行,可是已经没有数据可以接受了,所以我们定义守护进程,让他伴随主进程结束而结束
    p1.start()
    p2.start()
    c1.start()
    p1.join()
    p2.join()
    q.join() # 写再这里和卸载生产者语句里面是一样的
    print("打烊了")

原文地址:https://www.cnblogs.com/xiongchao0823/p/11527617.html

时间: 2024-10-09 13:16:57

进程 >> 互斥锁、队列与管道、生产者消费者模型的相关文章

如何使用阻塞队列来实现生产者-消费者模型?

什么是阻塞队列?如何使用阻塞队列来实现生产者-消费者模型? java.util.concurrent.BlockingQueue的特性是:当队列是空的时,从队列中获取或删除元素的操作将会被阻塞,或者当队列是满时,往队列里添加元素的操作会被阻塞. 阻塞队列不接受空值,当你尝试向队列中添加空值的时候,它会抛出NullPointerException. 阻塞队列的实现都是线程安全的,所有的查询方法都是原子的并且使用了内部锁或者其他形式的并发控制. BlockingQueue 接口是java colle

python并发编程之多进程(二):互斥锁(同步锁)&进程其他属性&进程间通信(queue)&生产者消费者模型

一,互斥锁,同步锁 进程之间数据不共享,但是共享同一套文件系统,所以访问同一个文件,或同一个打印终端,是没有问题的, 竞争带来的结果就是错乱,如何控制,就是加锁处理 part1:多个进程共享同一打印终端 #并发运行,效率高,但竞争同一打印终端,带来了打印错乱 from multiprocessing import Process import os,time def work(): print('%s is running' %os.getpid()) time.sleep(2) print('

10.22进程互斥锁,队列,堆栈,线程

进程互斥锁 让并发变成串行,牺牲了执行效率,保证了数据的安全. 在程序并发执行时,如果需要修改数据就使用互斥锁. 队列 相当于内存中的空间. 可以存放多个数据,必须排队,遵循先进先出的顺序. from multiprocessing import Queue #调用队列类,实例化队列对象q q = Queue(5) #若传参,队列中就可以存放5个数据 q = Queue() #若不传参,则队列中可以存放无限个数据 q.get() #获取数据 q.put() #添加数据,满了就报错 q.empty

Python学习笔记——进阶篇【第九周】———线程、进程、协程篇(队列Queue和生产者消费者模型)

Python之路,进程.线程.协程篇 本节内容 进程.与线程区别 cpu运行原理 python GIL全局解释器锁 线程 语法 join 线程锁之Lock\Rlock\信号量 将线程变为守护进程 Event事件 queue队列 生产者消费者模型 Queue队列 开发一个线程池 进程 语法 进程间通讯 进程池 参考链接http://www.cnblogs.com/alex3714/articles/5230609.html

线程同步和互斥(条件变量控制生产者消费者模型)

条件变量 生产者消费者模型: 关系:      同步 生产者<----->消费者    互斥 互斥 生产者<----->生产者       互斥 消费者<----->消费者   场所:   缓冲区,下文以链表方式实现 1.单个生产者,单个消费者,且生产者和消费者访问链表的顺序是LIFO的 代码实现: #include<stdio.h> #include<pthread.h> pthread_mutex_t _mutex_lock=PTHREAD_

queue队列,以及生产者消费者模型

queue 队列!特点是有序的,跟list的区别,list调用元素,其实就是复制,还要用remove给删掉,麻烦,queue更加方便 生成队列的方法: class queue.Queue(maxsize=0) #先入先出  #maxsize可以设定队列大小 class queue.LifoQueue(maxsize=0) #last in fisrt out  后进先出,例如卖东西,大家都喜欢新鲜的 class queue.PriorityQueue(maxsize=0) #存储数据时可设置优先

Python 再次改进版通过队列实现一个生产者消费者模型

import time from multiprocessing import Process,Queue #生产者 def producer(q): for i in range(10): time.sleep(0.2) s = '大包子%s号'%i print(s+'新鲜出炉,拿去用') q.put(s) q.put(None) #发送一个任务结束信号,来中断消费者的程序 def consumer(q): while 1: time.sleep(0.5) baozi = q.get() if

Python 通过队列实现一个生产者消费者模型

import time from multiprocessing import Process,Queue #生产者 def producer(q): for i in range(10): time.sleep(0.7) s = '大包子%s号'%i print(s+'新鲜出炉,拿去用') q.put(s) def consumer(q): while 1: time.sleep(1) baozi = q.get() print(baozi+'被吃了') if __name__ == '__m

生产者消费者模型

生产者消费者模型是经典的模型,我们都知道,在实际的软件开发中,某个模块负责生产数据,某个模块负责处理数据,产生数据的模块,就形象地成为生产者,而处理数据的模块,被称为消费者. 我们知道,该模式还需要一个缓冲区处于生产者和消费者之间,作为一个中介,生产者把数据放入缓冲区,而消费者从缓冲区取出数据. 我们下面基于条件变量和互斥锁,写一个生产者消费者模型的例子: 代码如下:    #include <stdio.h>     #include <stdlib.h>     #includ

joinablequeue模块 生产者消费者模型 Manager模块 进程池 管道

一.生产者消费者 主要是为解耦(借助队列来实现生产者消费者模型) import queue  # 不能进行多进程之间的数据传输 (1)from multiprocessing import Queue    借助Queue解决生产者消费者模型,队列是安全的. q = Queue(num) num :为队列的最大长度 q.get() # 阻塞等待获取数据,如果有数据直接获取,如果没有数据,阻塞等待 q.put() # 阻塞,如果可以继续往队列中放数据,就直接放,不能放就阻塞等待 q.get_now