python学习笔记 - 对进程的管理 Lock、Semaphore、Event

前面的文章介绍了如何进行进程间的通讯方式。结下来咱们来说一讲如何管理多个进程对资源的访问。
例若有时候咱们多个进程对某一个文件进行写入的时候,若是咱们一个进程尚未写完,就被CPU切换到另外一个进程,势必会形成文件写入的顺序乱七八糟的。正确的状况是,在一个进程写完的时候,再让另外一个进程进行写入。这时候,咱们须要一个锁。windows

Lock

Lock有一点像咱们平常生活中上厕所。厕所就是咱们的资源,能够解决咱们的需求。可是厕所是有限的,并且一次只能进去一我的。同时想上厕所的人不少,还没轮到的人所有在外边等待,轮到的人能够进去使用厕所,同时会锁上门,禁止其余人进入。上完厕所的人出来,打开厕所门,让后面的人进来。
翻译成计算机语言就是:
这个资源只容许一个Process访问,所以只有一个门,上一把锁。
图片描述app

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())+"\r")


if __name__ == '__main__':
    lock = Lock()
    pool = Pool()
    for i in range(0, 10):
        pool.apply_async(write_file(lock))
    pool.close()

注意: lock其实跟文件的打开关闭同样,可使用with语句。dom

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语句的话,则须要手动写:async

lock.acquire()
lock.release()

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

RLock

RLock是Lock的递归版。啥意思呢?
咱们知道lock.aquire()是请求锁,当当前的锁事锁定状态的时候,则lock.aquire()则会阻塞等待锁释放。
所以若是咱们写了两个lock.aquire()则会产生死锁。第二个lock.aquire()会永远等待在那里。spa

使用RLock则不会有这种状况。RLock一个门支持多个锁,上多少把锁,就得释放多少次。
图片描述翻译

Semaphore

Semaphore有信号灯的意思。
Semaphore跟Lock相似,可是Semaphore能够容许指定最多多少个进程访问资源。
就像该资源有多个门,每一个门一把锁。一个进程访问了资源,锁了门,还有其余门可使用。可是若是全部门都被使用了,那么就得等待有进程出来释放锁才能够。
图片描述
在编写Sempaphore示例代码的时候,遇到了一个比较奇怪的问题。unix

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下出错)code

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。Event也是用于进程间的通讯,那么它跟Queue、Pipe有什么区别呢?

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

相关文章
相关标签/搜索