博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
python学习笔记 - 对进程的管理 Lock、Semaphore、Event
阅读量:6173 次
发布时间:2019-06-21

本文共 2498 字,大约阅读时间需要 8 分钟。

前面的文章介绍了如何进行进程间的通信方式。结下来我们来讲一讲如何管理多个进程对资源的访问。

例如有时候我们多个进程对某一个文件进行写入的时候,如果我们一个进程还没有写完,就被CPU切换到另一个进程,势必会造成文件写入的顺序乱七八糟的。正确的情况是,在一个进程写完的时候,再让另一个进程进行写入。这时候,我们需要一个锁。

Lock

Lock有一点像我们日常生活中上厕所。厕所就是我们的资源,可以解决我们的需求。但是厕所是有限的,而且一次只能进去一个人。同时想上厕所的人很多,还没轮到的人全部在外边等待,轮到的人可以进去使用厕所,同时会锁上门,禁止其他人进入。上完厕所的人出来,打开厕所门,让后面的人进来。

翻译成计算机语言就是:
这个资源只允许一个Process访问,因此只有一个门,上一把锁。
图片描述

from multiprocessing import Lock, Poolimport randomdef write_file(lock):    with lock:        with open('write_demo.txt', 'a') as wf:            wf.write(str(random.random())+"\r")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()

两者之间的代码才是被锁保护的。

RLock

RLock是Lock的递归版。啥意思呢?

我们知道lock.aquire()是请求锁,当当前的锁事锁定状态的时候,则lock.aquire()则会阻塞等待锁释放。
因此如果我们写了两个lock.aquire()则会产生死锁。第二个lock.aquire()会永远等待在那里。

使用RLock则不会有这种情况。RLock一个门支持多个锁,上多少把锁,就得释放多少次。

图片描述

Semaphore

Semaphore有信号灯的意思。

Semaphore跟Lock类似,但是Semaphore可以允许指定最多多少个进程访问资源。
就像该资源有多个门,每个门一把锁。一个进程访问了资源,锁了门,还有其他门可以使用。但是如果所有门都被使用了,那么就得等待有进程出来释放锁才可以。
图片描述
在编写Sempaphore示例代码的时候,遇到了一个比较奇怪的问题。

from multiprocessing import Semaphore, Poolimport osimport timedef 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, Poolimport osimport timesemaphore = 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。Event也是用于进程间的通信,那么它跟Queue、Pipe有什么区别呢?

其实Python多进程还有许多的内容。在后续的文章中介绍。

转载地址:http://rmqba.baihongyu.com/

你可能感兴趣的文章
Apache 单IP多端口设置
查看>>
安装系统前的准备---vmware
查看>>
Tiny并行计算框架之使用介绍
查看>>
Linux od命令
查看>>
一个不错的MySQL集群管理工具
查看>>
mysql-proxy 按表分发查询的lua脚本
查看>>
在wordpress主题下面添加二级菜单
查看>>
结合MongoDB开发LBS应用
查看>>
CentOS 下JDK安装
查看>>
从点名信想到母亲的一件事
查看>>
Nginx + Django
查看>>
我的友情链接
查看>>
cnetos7更改网卡类型
查看>>
用shell脚本编写进度条
查看>>
使用Live555类库实现的网络直播系统
查看>>
MySQL的使用
查看>>
分我一半的眼泪代码
查看>>
国内Saas2.0还有多远要走
查看>>
同步synchronized方法和代码块
查看>>
IO与NIO
查看>>