摘要:前面的文章介绍了如何进行进程间的通信方式。结下来我们来讲一讲如何管理多个进程对资源的访问。正确的情况是,在一个进程写完的时候,再让另一个进程进行写入。那么后的代码块都是被所保护。怀疑会在下出错以上代码可以正确执行。
前面的文章介绍了如何进行进程间的通信方式。结下来我们来讲一讲如何管理多个进程对资源的访问。
例如有时候我们多个进程对某一个文件进行写入的时候,如果我们一个进程还没有写完,就被CPU切换到另一个进程,势必会造成文件写入的顺序乱七八糟的。正确的情况是,在一个进程写完的时候,再让另一个进程进行写入。这时候,我们需要一个锁。
Lock有一点像我们日常生活中上厕所。厕所就是我们的资源,可以解决我们的需求。但是厕所是有限的,而且一次只能进去一个人。同时想上厕所的人很多,还没轮到的人全部在外边等待,轮到的人可以进去使用厕所,同时会锁上门,禁止其他人进入。上完厕所的人出来,打开厕所门,让后面的人进来。
翻译成计算机语言就是:
这个资源只允许一个Process访问,因此只有一个门,上一把锁。
from multiprocessing import Lock, Pool import random def write_file(lock): with lock: with open("write_demo.txt", "a") as wf: wf.write(str(random.random())+" ") if __name__ == "__main__": lock = Lock() pool = Pool() for i in range(0, 10): pool.apply_async(write_file(lock)) pool.close()
注意: lock其实跟文件的打开关闭一样,可以使用with语句。
Lock supports the context manager protocol and thus may be used in with statements.
解释一下这里为什么是with lock:因为在if __name__ == "__main__":中我们已经创建了Lock对象。而with后是需要跟一个对象,因此直接将lock写在后面即可。那么with后的代码块都是被with所保护。
如果不用with语句的话,则需要手动写:
lock.acquire() lock.release()
两者之间的代码才是被锁保护的。
RLockRLock是Lock的递归版。啥意思呢?
我们知道lock.aquire()是请求锁,当当前的锁事锁定状态的时候,则lock.aquire()则会阻塞等待锁释放。
因此如果我们写了两个lock.aquire()则会产生死锁。第二个lock.aquire()会永远等待在那里。
使用RLock则不会有这种情况。RLock一个门支持多个锁,上多少把锁,就得释放多少次。
Semaphore有信号灯的意思。
Semaphore跟Lock类似,但是Semaphore可以允许指定最多多少个进程访问资源。
就像该资源有多个门,每个门一把锁。一个进程访问了资源,锁了门,还有其他门可以使用。但是如果所有门都被使用了,那么就得等待有进程出来释放锁才可以。
在编写Sempaphore示例代码的时候,遇到了一个比较奇怪的问题。
from multiprocessing import Semaphore, Pool import os import time def worker_process(s): print id(s) with s: print "Process (%s) run" % os.getpid() time.sleep(1) print "Process (%s) ended" % os.getpid() if __name__ == "__main__": semaphore = Semaphore(1) print id(semaphore) pool = Pool(4) for i in range(0, 1000): pool.apply_async(worker_process, args=(semaphore,)) pool.close() pool.join() print "Main Process ended"
如上所示的代码,传递semaphore时候,worker_process并不会执行。
但是如果将semaphore定义成一个全局变量,那么则可以在Linux或者unix下执行。(怀疑会在windows下出错)
from multiprocessing import Semaphore, Pool import os import time semaphore = Semaphore(1) def worker_process(): print id(semaphore) with semaphore: print "Process (%s) run" % os.getpid() time.sleep(1) print "Process (%s) ended" % os.getpid() if __name__ == "__main__": print id(semaphore) pool = Pool(4) for i in range(0, 1000): pool.apply_async(worker_process) pool.close() pool.join() print "Main Process ended"
以上代码可以正确执行。
暂时不知道问题出在哪里?有会的网友还请指点。
还有Event。Event也是用于进程间的通信,那么它跟Queue、Pipe有什么区别呢?
其实Python多进程还有许多的内容。在后续的文章中介绍。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/38356.html
摘要:连接带远程管理器对象,该对象的地址在构造函数中支出。在当前进程中运行管理器服务器。启动一个单的子进程,并在该子进程中启动管理器服务器。如果无法序列号对象将引发异常。 上一篇文章:Python进程专题6:共享数据与同步下一篇文章:Python进程专题8:分布集群的消息传递 进程不支持共享对象,上面描述的创建共享值和数组,但都是指定的特殊类型,对高级的Python对象(如:字典、列表、用...
摘要:很简单,这个模块实现了开辟一块共享内存空间,就好比中的方法一样,有兴趣的同学可以去查阅。查了下资料,返回的对象控制了一个进程,可用于多进程之间的安全通信,其支持的类型有和等。 有关于 multiprocessing 中共享变量的问题 现在的cpu都很强大,比方我用的至强2620有24核可以同时工作,并行执行进程程序。这在计算密集型的程序是很需要的,如沙漠中的绿洲,令人重获新生。那么,问...
摘要:可以使用标准的索引切片迭代操作访问它,其中每项操作均锁进程同步,对于字节字符串,还具有属性,可以把整个数组当做一个字符串进行访问。当所编写的程序必须一次性操作大量的数组项时,如果同时使用这种数据类型和用于同步的单独大的锁,性能将极大提升。 上一篇文章:Python进程专题5:进程间通信下一篇文章:Python进程专题7:托管对象 我们现在知道,进程之间彼此是孤立的,唯一通信的方式是队...
摘要:某进程内的线程在其它进程不可见。线程的实体包括程序数据和。包括以下信息线程状态。当线程不运行时,被保存的现场资源。用户级线程执行系统调用指令时将导致其所属进程被中断,而内核支持线程执行系统调用指令时,只导致该线程被中断。线程能够利用的表空 操作系统线程理论 线程概念的引入背景 进程之前我们已经了解了操作系统中进程的概念,程序并不能单独运行,只有将程序装载到内存中,系统为它分配资源才能运...
摘要:第四章分布式和并行计算来源译者飞龙协议引言目前为止,我们专注于如何创建解释和执行程序。一个交互的例子就是在线阅读纽约时报。当上的服务器与浏览器客户端比如通信时,它的任务就是发送回来纽约时报主页的。消息有三个必要部分发送者接收者和内容。 第四章 分布式和并行计算 来源:Chapter 4: Distributed and Parallel Computing 译者:飞龙 协议:CC B...
阅读 861·2021-09-29 09:35
阅读 1220·2021-09-28 09:36
阅读 1486·2021-09-24 10:38
阅读 1017·2021-09-10 11:18
阅读 607·2019-08-30 15:54
阅读 2476·2019-08-30 13:22
阅读 1928·2019-08-30 11:14
阅读 664·2019-08-29 12:35