生产者消费者问题

互斥锁和进程之间的通信

拟墨画扇 提交于 2020-01-15 18:21:47
互斥锁 进程之间数据隔离,但是共享一套文件系统,因而可以通过文件来实现进程直接的通信,但问题是必须自己加锁处理。 注意:加锁的目的是为了保证多个进程修改同一块数据时,同一时间只能有一个修改,即串行的修改,没错,速度是慢了,牺牲了速度而保证了数据安全。 示例一.上厕所 你上厕所的时候肯定得锁门吧,有人来了看见门锁着,就会在外面等着,等你吧门开开出来的时候,下一个人才去上厕所。 1 from multiprocessing import Process,Lock 2 import os 3 import time 4 def work(mutex): 5 mutex.acquire() 6 print('task[%s] 上厕所'%os.getpid()) 7 time.sleep(3) 8 print('task[%s] 上完厕所'%os.getpid()) 9 mutex.release() 10 if __name__ == '__main__': 11 mutex = Lock() 12 p1 = Process(target=work,args=(mutex,)) 13 p2 = Process(target=work,args=(mutex,)) 14 p3 = Process(target=work,args=(mutex,)) 15 p1.start() 16 p2

python并发编程之多进程1-----------互斥锁与进程间的通信

自闭症网瘾萝莉.ら 提交于 2020-01-15 18:21:05
python并发编程之多进程1-----------互斥锁与进程间的通信 一、互斥锁 进程之间数据隔离,但是共享一套文件系统,因而可以通过文件来实现进程直接的通信,但问题是必须自己加锁处理。 注意:加锁的目的是为了保证多个进程修改同一块数据时,同一时间只能有一个修改,即串行的修改,没错,速度是慢了,牺牲了速度而保证了数据安全。 1.上厕所的小例子:你上厕所的时候肯定得锁门吧,有人来了看见门锁着,就会在外面等着,等你吧门开开出来的时候,下一个人才去上厕所。 1 from multiprocessing import Process,Lock 2 import os 3 import time 4 def work(mutex): 5 mutex.acquire() 6 print('task[%s] 上厕所'%os.getpid()) 7 time.sleep(3) 8 print('task[%s] 上完厕所'%os.getpid()) 9 mutex.release() 10 if __name__ == '__main__': 11 mutex = Lock() 12 p1 = Process(target=work,args=(mutex,)) 13 p2 = Process(target=work,args=(mutex,)) 14 p3 = Process(target

线程

旧街凉风 提交于 2020-01-15 06:19:26
多进程多线程的join和队列的join是不一样的 进程队列 q=multiprocess.Queue() 多个进程之间能通信(不建议,一般用管道实现进程间通信) 线程队列 q=queue.Queue() 多个线程之间能通信 多进程同步中的Lock ,需要传给Process 多线程的 进程线程的特点 每个进程都有自己 独立的 内存地址 线程之间的切换 相对于 进程之间切换 更为方便,代价也更低。 对于IO密集型的任务,使用多线程还是能提高一下CPU使用率。 对于CPU密集型的任务,Python中的多线程其实是个鸡肋……没卵用……在Python的解释器CPython中存在一个互斥锁。简单来讲就是同一时间只能有一个线程在执行,其它线程都处于block模式。 要想在py中充分利用多核cpu,就只能用多进程了。虽然代价高了些,但是比起并行计算带来的性能提升这些也微不足道了。 进程与线程的关系区别 一个程序至少有一个进程,一个进程至少有一个线程.(进程可以理解成线程的容器)进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提高了程序的运行效率。线程在执行过程中与进程还是有区别的。每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口。但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。 进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动

线程认识

落爺英雄遲暮 提交于 2020-01-14 08:37:30
线程是为了让程序更好的利用cpu资源,在并行/并发处理下比进程切换cpu使用所要的花销要小。 在一个程序里的一个执行路线就叫做线程(thread)。更准确的定义是:线程是“一个进程内部的控制序列”。一切进程至少都有一个执行线程。线程在进程内部运行,本质是在进程地址空间内运行。在Linux系统中,在CPU眼中,看到的PCB都要比传统的进程更加轻量化( Linux中可以称为轻量级进程(LWP) )。透过进程虚拟地址空间,可以看到进程的大部分资源,将进程资源合理分配给每个执行流,就形成了线程执行流。 结合生活中的例子,创建一个进程就相当于工厂新建了一个厂子, 而创建一个线程就相当于在原厂的基础上增加一条生产线 ,在这方面也能看出创建新进程会分配新的虚拟地址空间,而 创建新的线程则会共用原来的虚拟地址空间(创建进程会拷贝原有的PCB并指向原有的虚拟地址空间) 。那么进程和线程的区别是什么呢?进程的作用更多是资源的管理(管理内存、文件),而 线程的作用更多是负责资源的调度和执行(也是抢占式的调度)。 ------>线程之间共用虚拟地址空间和文件描述符表 ------>线程之间不共用的资源:①栈(函数调用栈、局部变量),每个线程的栈是不共用的但不是私有的,别的线程也可以用②上下文信息(cpu中寄存器数据保存在内存中,方便下次执行)③errno错误码

线程认识

我的未来我决定 提交于 2020-01-14 08:37:20
线程是为了让程序更好的利用cpu资源,在并行/并发处理下比进程切换cpu使用所要的花销要小。 在一个程序里的一个执行路线就叫做线程(thread)。更准确的定义是:线程是“一个进程内部的控制序列”。一切进程至少都有一个执行线程。线程在进程内部运行,本质是在进程地址空间内运行。在Linux系统中,在CPU眼中,看到的PCB都要比传统的进程更加轻量化( Linux中可以称为轻量级进程(LWP) )。透过进程虚拟地址空间,可以看到进程的大部分资源,将进程资源合理分配给每个执行流,就形成了线程执行流。 结合生活中的例子,创建一个进程就相当于工厂新建了一个厂子, 而创建一个线程就相当于在原厂的基础上增加一条生产线 ,在这方面也能看出创建新进程会分配新的虚拟地址空间,而 创建新的线程则会共用原来的虚拟地址空间(创建进程会拷贝原有的PCB并指向原有的虚拟地址空间) 。那么进程和线程的区别是什么呢?进程的作用更多是资源的管理(管理内存、文件),而 线程的作用更多是负责资源的调度和执行(也是抢占式的调度)。 ------>线程之间共用虚拟地址空间和文件描述符表 ------>线程之间不共用的资源:①栈(函数调用栈、局部变量),每个线程的栈是不共用的但不是私有的,别的线程也可以用②上下文信息(cpu中寄存器数据保存在内存中,方便下次执行)③errno错误码

Java 多线程间的通讯

瘦欲@ 提交于 2020-01-13 20:32:26
问题 在前一小节,介绍了在多线程编程中使用同步机制的重要性,并学会了如何实现同步的方法来正确地访问共享资源。这些线程之间的关系是平等的,彼此之间并不存在任何依赖,它们各自竞争CPU资源,互不相让,并且还无条件地阻止其他线程对共享资源的异步访问。然而,也有很多现实问题要求不仅要同步的访问同一共享资源,而且线程间还彼此牵制,通过相互通信来向前推进。那么,多个线程之间是如何进行通信的呢? 解决思路 在现实应用中,很多时候都需要让多个线程按照一定的次序来访问共享资源,例如,经典的生产者和消费者问题。这类问题描述了这样一种情况,假设仓库中只能存放一件产品,生产者将生产出来的产品放入仓库,消费者将仓库中的产品取走消费。如果仓库中没有产品,则生产者可以将产品放入仓库,否则停止生产并等待,直到仓库中的产品被消费者取走为止。如果仓库中放有产品,则消费者可以将产品取走消费,否则停止消费并等待,直到仓库中再次放入产品为止。显然,这是一个同步问题,生产者和消费者共享同一资源,并且,生产者和消费者之间彼此依赖,互为条件向前推进。但是,该如何编写程序来解决这个问题呢? 传统的思路是利用循环检测的方式来实现,这种方式通过重复检查某一个特定条件是否成立来决定线程的推进顺序。比如,一旦生产者生产结束,它就继续利用循环检测来判断仓库中的产品是否被消费者消费

RabbitMQ(1)

梦想的初衷 提交于 2020-01-13 04:51:43
文章目录 RabbitMQ 1 基本概念 2 安装 3 核心概念 交换器类型 4 入门demo 客户端开发相关说明 1 exchangeDeclare方法 2 queueDeclare方法 3 消费消息 4 消费的确认与拒绝 5 消息的可靠性投递 消息可靠性投递解决方案 RabbitMQ 1 基本概念 消息 (Message) 是指在应用间传送的数据。消息可以非常简单,比如只包含文本字符串、JSON 等,也可以很复杂,比如内嵌对象。 消息队列中间件 (Message Queue Middleware,简称为 MQ) (消息队列或者消息中间件)是指利用高效可靠的消息传递机制进行与平台无关的数据交流,并基于数据通信来进行分布式系统的集成。通过提供消息传递和消息排队模型,它可以在分布式环境下扩展进程间的通信。 两种传递模式:点对点(P2P, Point-to-Point) 模式和发布/订阅 (Pub/Sub) 模式 比较主流的有 RabbitMQ,Kafka,ActiveMQ, RocketMQ等。 面向消息的中间件(简称为 MOM , Message Oriented Middleware) 提供了以松散藕合的灵活方式集成应用程序的一种机制。它们提供了基于存储和转发的应用程序之间的异步数据发送,即应用程序彼此不直接通信,而是与作为中介的消息中间件通信 。

RabbitMQ工作模型

梦想与她 提交于 2020-01-08 13:52:49
典型应用场景 1、跨系统的异步通信 人民银行二代支付系统,使用重量级消息队列 IBM MQ,异步,解耦,削峰都有体现。 2、应用内的同步变成异步 3、基于Pub/Sub模型实现的事件驱动 放款失败通知、提货通知、购买碎屏保 系统间同步数据 摒弃ELT(比如全量 同步商户数据); 摒弃API(比如定时增量获取用户、获取产品,变成增量广播)。 4、利用RabbitMQ实现事务的最终一致性。 基本介绍 AMQP协议 AMQP,即Advanced Message Queuing Protocol,一个提供统一消息服务的应用层标准高级消息队列协议,是应 用层协议的一个开放标准,为面向消息的中间件设计。基于此协议的客户端与消息中间件可传递消息,并不受客户 端/中间件同产品、不同的开发语言等条件的限制。 AMQP的实现有:RabbitMQ、OpenAMQ、Apache Qpid、Redhat Enterprise MRG、AMQP Infrastructure、 ØMQ、Zyre等。 RabbitMQ的特性 RabbitMQ使用Erlang语言编写,使用Mnesia数据库存储消息。 (1)可靠性(Reliability) RabbitMQ 使用一些机制来保证可靠性,如持久化、传输确认、发布确认。(2)灵活的路由(Flexible Routing) 在消息进入队列之前,通过 Exchange

Java多线程之ReentrantLock与Condition

假如想象 提交于 2019-12-27 00:01:46
一、ReentrantLock 1、ReentrantLock简介 ReentrantLock是一个可重入的互斥锁,又被称为“独占锁”。ReentrantLock 类实现了 Lock ,它拥有与 synchronized 相同的并发性和内存语义,但是添加了类似锁投票、定时锁等候和可中断锁等候的一些特性。此外,它还提供了在激烈争用情况下更佳的性能。(换句话说,当许多线程都想访问共享资源时,JVM 可以花更少的时候来调度线程,把更多时间用在执行线程上。) 顾名思义,ReentrantLock锁在同一个时间点只能被一个线程锁持有;而可重入的意思是,ReentrantLock锁,可以被单个线程多次获取。 ReentrantLock分为“ 公平锁 ”和“ 非公平锁 ”。它们的区别体现在获取锁的机制上是否公平。“锁”是为了保护竞争资源,防止多个线程同时操作线程而出错, ReentrantLock在同一个时间点只能被一个线程获取(当某线程获取到“锁”时,其它线程就必须等待);ReentraantLock是通过一个FIFO的等待队列来管理获取该锁所有线程的。在“公平锁”的机制下,线程依次排队获取锁;而“非公平锁”在锁是可获取状态时,不管自己是不是在队列的开头都会获取锁。 2、ReentrantLock函数列表 // 创建一个 ReentrantLock ,默认是“非公平锁”。

并发编程-队列与管道

时光毁灭记忆、已成空白 提交于 2019-12-26 23:44:19
加锁可以保证多个进程修改同一块数据时,同一时间只能有一个任务可以进行修改,即串行的修改,速度是慢了,但牺牲了速度却保证了数据安全。 虽然可以用文件共享数据实现进程间通信,但问题是: 1.效率低(共享数据基于文件,而文件是硬盘上的数据) 2.需要自己加锁处理。 因此我们最好找寻一种解决方案能够兼顾:1、效率高(多个进程共享一块内存的数据)2、帮我们处理好锁问题。 这就是mutiprocessing模块为我们提供的基于消息的IPC通信机制:队列和管道。 1 队列和管道都是将数据存放于内存中 2 队列又是基于(管道+锁)实现的,可以让我们从复杂的锁问题中解脱出来, 我们应该尽量避免使用共享数据,尽可能使用消息传递和队列,避免处理复杂的同步和锁问题,而且在进程数目增多时,往往可以获得更好的可获展性。 队列: 创建队列的类(底层就是以管道和锁定的方式实现) : 1 Queue([maxsize]):创建共享的进程队列,Queue是多进程安全的队列,可以使用Queue实现多进程之间的数据传递。参数介绍: maxsize是队列中允许最大项数,省略则无大小限制。 主要方法: 1 q.put方法用以插入数据到队列中,put方法还有两个可选参数:blocked和timeout。如果blocked为True(默认值),并且timeout为正值,该方法会阻塞timeout指定的时间,直到该队列有剩余的空间