Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用哪种机制来正确释放多个线程获取的资源_Python_Multithreading - Fatal编程技术网

Python 使用哪种机制来正确释放多个线程获取的资源

Python 使用哪种机制来正确释放多个线程获取的资源,python,multithreading,Python,Multithreading,假设我有以下两个函数。第一个(use\u stuff)可以被许多线程用来做一些计算,而第二个(clean\u stuff\u cache)可以在需要更新缓存时偶尔在单独的线程中调用。我应该使用哪种同步机制(我在这里称之为计数器)来确保clean_stuff_缓存将阻塞,直到所有线程完成use_stuff例程 stuff_cache = dict() counter = ???? def use_stuff(id): counter.acquire() if id not in s

假设我有以下两个函数。第一个(
use\u stuff
)可以被许多线程用来做一些计算,而第二个(
clean\u stuff\u cache
)可以在需要更新缓存时偶尔在单独的线程中调用。我应该使用哪种同步机制(我在这里称之为
计数器
)来确保
clean_stuff_缓存
将阻塞,直到所有线程完成
use_stuff
例程

stuff_cache = dict()
counter = ????

def use_stuff(id):
   counter.acquire()

   if id not in stuff_cache:
      stuff_cache[id] = get_stuff(id)
   # do some computation using stuff
   do_stuff(stuff_cache[id])

   counter.release()

def clean_stuff_cache(id):
   counter.wait_until_zero()
   # drop all the stuff being used
   del stuff[id]

您可以在这里使用
信号量
对象与
组合。当信号量为0时,如果您试图获取if,则该信号量允许有一个同步计数器阻止该计数器。
因此,如果
计数器=信号量(0)
,并且
锁=锁()
,则:

def use_stuff(id):
    # Increment number of running workers if your are not cleaning the cache
    with lock:
        counter.release()
    ..... do stuff...
    # decrement number of running workers
    counter.acquire()

def clean_stuff():
    # counter.acquire return False if there is no worker running
    while True:
        lock.acquire()
        if counter.acquire(False):
            counter.release()
            lock.release()
        else:
            break

        # delay next loop so the check is only occasional
        time.sleep(.01)

    # here, no worker is running and the lock prevents new worker
    # from starting so you can cleanup the cache...
    ... do clean up
    lock.release()

您可以尝试信号,比如当线程想要刷新缓存时,向其他线程发送信号,以便它们可以退出/sotp/暂停,在清理缓存后,只需向restart发送另一个信号我采用了您的方法(它工作得很好),还构建了我自己的方法来创建可重用的装饰器(请参见此处的两个)