美文网首页
Python对进程/线程锁的一些理解

Python对进程/线程锁的一些理解

作者: 曲谐_ | 来源:发表于2018-12-16 15:45 被阅读0次

    看multiprocessing部分的Python文档,一点思考:
    https://www.rddoc.com/doc/Python/3.6.0/zh/library/multiprocessing/#module-multiprocessing
    离职啦,感觉一直拖拖拖,现在反而清醒轻松了不少,开始疯狂产出吧~


    from multiprocessing import Process, Lock
    
    def f(l, i):
        l.acquire()
        try:
            print('hello world', i)
        finally:
            l.release()
    
    if __name__ == '__main__':
        lock = Lock()
    
        for num in range(10):
            Process(target=f, args=(lock, num)).start()
    

    这里给进程设置了一个进程锁lock。lock在不同进程使用同一共享内存时,能够确保线程之间互不影响,使用lock的方法是, 在每个线程/进程使用共享内存资源或修改共享内存之前,执行lock.acquire()将共享内存上锁, 确保当前进程执行时,内存不会被其他进程访问,执行运算完毕后,使用lock.release()将锁打开, 保证其他的线程可以使用该共享内存。
    看似这样做,进程就会输出0-9了,但实际上并不会。

    # output result
    hello world 0
    hello world 1
    hello world 5
    hello world 2
    hello world 4
    hello world 7
    hello world 3
    hello world 6
    hello world 8
    hello world 9
    

    可见,第一个进程必然是0,这毫无疑问,但后面却散乱排布。这与使用锁的初衷相违背,这是为什么呢?
    思考后发现,在第一个进程执行的过程中,即i=0时,它拥有当前的lock,因此它必然是先执行的。但是由于进程是非阻塞的,因此在执行Process的过程中,还是可以继续迭代的,即num=1,2,...,9这个过程中他们都有可能进入Process这一步,等待num=0时执行函数结束,获得当前的Process,因此后面的顺序是不可控的。
    如果想要按顺序排布,可以将进程设置为阻塞的。即当前进程执行完之前,后面的进程会先挂起。这可以通过join()函数来实现。

    # blocking
    from multiprocessing import Process, Lock
    
    def f(l, i):
        l.acquire()
        try:
            print('hello world', i)
        finally:
            l.release()
    
    if __name__ == '__main__':
        lock = Lock()
    
        for num in range(10):
            p = Process(target=f, args=(lock, num))
            p.start()
            p.join()
    

    输出结果为:

    # output result
    hello world 0
    hello world 1
    hello world 2
    hello world 3
    hello world 4
    hello world 5
    hello world 6
    hello world 7
    hello world 8
    hello world 9
    

    相关文章

      网友评论

          本文标题:Python对进程/线程锁的一些理解

          本文链接:https://www.haomeiwen.com/subject/bukdqqtx.html