Python-如何在类实例中使用多处理锁? [英] Python - How to use multiprocessing Lock in class instance?

查看:72
本文介绍了Python-如何在类实例中使用多处理锁?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在Windows上使用Python 3.7.

I am using Python 3.7 on Windows.

我正在尝试做的事情:-当另一个进程获得相同的锁时,锁定该类实例的方法.

What I am trying to do: - lock a method of an instance of a class, when another process has acquired that same lock.

尝试:

我已经成功完成了,但是我不想在这里使用全局变量锁定,而是完全在类内部

I have already successfully done this, but I don't want a global variable here for the lock, but instead one completely internal to the class

from multiprocessing import Lock, freeze_support,Pool
from time import sleep

def do_work(name):
    print(name+' waiting for lock to work...',end='')
    sleep(2)
    with lock:
        print('done!')
        print(name+' doing work...',end='')
        sleep(5)
        print('done!')

def init(olock):
    global lock
    lock = olock

if __name__ == '__main__':
    freeze_support()
    args_list = [('a'),('b'),('c')]
    lock=Lock()
    p=Pool(8,initializer=init,initargs=(lock,))
    p.map_async(do_work,args_list)
    p.close()
    p.join()

这最后一段代码运行时,由于锁定,它需要〜17.3秒.没有锁,它需要〜7秒.

When this last chunk of code runs, it takes ~17.3 seconds, because of the lock. Without the lock it takes ~7 seconds.

我试图在一个类中实现此操作,但是该锁没有执行任何操作,并且始终在〜7秒内运行.

I have tried to implement this inside a class, but the lock does nothing, and it always runs in ~7 seconds.

class O():
    def __init__(self):
        self.lock=Lock()
    def __getstate__(self): # used to remove multiprocess object(s) from class, so it can be pickled
        self_dict=self.__dict__.copy()
        del self_dict['lock']
        return self_dict
    def __setstate__(self,state): # used to remove multiprocess object(s) from class, so it can be pickled
        self.__dict__.update(state)
    def _do_work(self,name):
        print(name+' waiting for lock to work...',end='')
        sleep(2)
        with self.lock:
            print('done!')
            print(name+' doing work...',end='')
            sleep(5)
            print('done!')

if __name__ == '__main__':
    freeze_support()
    c = O()
    pool = Pool(8)
    pool.apply_async(c._do_work,('a',))
    pool.apply_async(c._do_work,('b',))
    pool.apply_async(c._do_work,('c',))
    pool.close()
    pool.join()

问题:那么,当我调用通过多处理与资源异步交互的方法时,如何锁定该类实例呢?

Question: So, what can I do to lock up this class instance while I call a method which interacts with a resource asynchronously through multiprocessing?

推荐答案

apply_async 将使函数对象腌制并按队列发送到池工作进程,但作为 c._do_work 是绑定方法,实例也会被腌制,从而导致错误.您可以将其包装在一个普通函数中:

apply_async will pickle function object and send to pool worker process by queue, but as c._do_work is a bound method, the instance will be pickled too, which results in an error. you could wrap it within a plain function:

c = O()
def w(*args):
    return c._do_work(*args)

if __name__ == '__main__':
    pool = Pool(1)
    pool.apply_async(w, ('a',))
    ...

,您应该删除 __ setstate __ / __ getstate __ .

这篇关于Python-如何在类实例中使用多处理锁?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆