Python知识——进程间通信、生产者与消费者模型、线程

进程间通信

IPC

主进程跟子进程借助于队列通信

from multiprocessing import Queue, Process


def producer(q):
    q.put('队列里面的信息')
    print('hello world')


if __name__ == '__main__':
    q = Queue()
    p = Process(target=producer, args=(q,))
    p.start()
    print(q.get())
'''
hello world
队列里面的信息
'''

子进程与子进程进行通信

from multiprocessing import Queue, Process


def producer(q):
    q.put('队列里面的信息')
    print('hello world')


def consumer(q):
    print(q.get())


if __name__ == '__main__':
    q = Queue()
    p = Process(target=producer, args=(q,))
    p1 = Process(target=consumer, args=(q,))
    p.start()
    p1.start()
'''
hello world
队列里面的信息
'''

生产者与消费者模型

在并发编程中使用生产者和消费者模式能够解决绝大多数并发问题。该模式通过平衡生产线程和消费线程的工作能力来提高程序的整体处理数据的速度。

为什么要使用生产者和消费者模式
在线程世界里,生产者就是生产数据的线程,消费者就是消费数据的线程。在多线程开发当中,如果生产者处理速度很快,而消费者处理速度很慢,那么生产者就必须等待消费者处理完,才能继续生产数据。同样的道理,如果消费者的处理能力大于生产者,那么消费者就必须等待生产者。为了解决这个问题于是引入了生产者和消费者模式。

什么是生产者消费者模式
生产者消费者模式是通过一个容器来解决生产者和消费者的强耦合问题。生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理,直接扔给阻塞队列,消费者不找生产者要数据,而是直接从阻塞队列里取,阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力。

from multiprocessing import Queue, Process, JoinableQueue
import time
import random

def producer(name, food, q):
    for i in range(5):
        data = '%s生产了%s%s' % (name, food, i)
        # 模拟延迟
        time.sleep(random.randint(1, 3))
        print(data)
        # 将数据丢入队列
        q.put(data)


def consumer(name, q):
    while True:
        food = q.get()
        time.sleep(random.randint(1, 3))
        print('%s吃了%s' % (name, food))
        q.task_done()  # 告诉队列已经从里面取出了一个数据并且处理完毕


if __name__ == '__main__':
    # q = Queue()
    q = JoinableQueue()
    p1 = Process(target=producer, args=('大厨', '包子', q))
    p2 = Process(target=producer, args=('tank', '饺子', q))
    c1 = Process(target=consumer, args=('张三', q))
    c2 = Process(target=consumer, args=('小三', q))
    p1.start()
    p2.start()
    c1.daemon = True
    c2.daemon = True
    c1.start()
    c2.start()
    p1.join()
    p2.join()
    q.join()  # 等待队列中所有的数据被取完再往下执行代码

'''
JoinableQueue 每当该队列中存入数据的时候,内部会有一个计数器+1
每当调用task_done的时候,计数器-1
q.join()当计数器为0的时候,才往后运行
'''
 # 只要q.join执行完毕,说明消费者已经处理完数据了,消费者就没有存在的必要了


'''
大厨生产了包子0
tank生产了饺子0
小三吃了大厨生产了包子0大厨生产了包子1

张三吃了tank生产了饺子0tank生产了饺子1
大厨生产了包子2

大厨生产了包子3
张三吃了大厨生产了包子2小三吃了大厨生产了包子1

大厨生产了包子4
tank生产了饺子2小三吃了大厨生产了包子3

张三吃了tank生产了饺子1
tank生产了饺子3小三吃了大厨生产了包子4

小三吃了tank生产了饺子3
张三吃了tank生产了饺子2
tank生产了饺子4
小三吃了tank生产了饺子4

'''

线程

在传统操作系统中,每个进程有一个地址空间,而且默认就有一个控制线程

线程顾名思义,就是一条流水线工作的过程,一条流水线必须属于一个车间,一个车间的工作过程是一个进程

车间负责把资源整合到一起,是一个资源单位,而一个车间内至少有一个流水线

流水线的工作需要电源,电源就相当于cpu

所以,进程只是用来把资源集中到一起(进程只是一个资源单位,或者说资源集合),而线程才是cpu上的执行单位。

多线程(即多个控制线程)的概念是,在一个进程中存在多个控制线程,多个控制线程共享该进程的地址空间,相当于一个车间内有多条流水线,都共用一个车间的资源

总结:
进程:资源单位(起一个进程仅仅是在内存空间中开辟一块独立的空间)
线程:执行单位(真正被cpu执行的其实是进程里面的线程,线程指的是代码的执行过程,执行代码中所需要使用到的资源都找所在的进程索要)

开启线程的两种方法

第一种:

import time
from threading import Thread


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


# 开启线程不需要在main下面执行代码,直接书写就可以
# 但是还是习惯性的将启动命令写在main下面

if __name__ == '__main__':
    t = Thread(target=task, args=('egon',))
    t.start()  # 创建线程的开销非常小  几乎是代码一执行,线程就可以创建了
    print('主')

第二种:

class MyThead(Thread):
    def __init__(self,name):
        super().__init__()
        self.name = name

    def run(self):
        print('%s is running' %self.name)
        time.sleep(1)
        print('%s is over' % self.name)

if __name__ == '__main__':

    t = MyThead('egon')
    t.start()
    print('主')
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值