Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/339.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_Locking_Eval - Fatal编程技术网

Python 评估锁不存在';行不通

Python 评估锁不存在';行不通,python,locking,eval,Python,Locking,Eval,我正在尝试为类似的输入字符串设置锁。但是锁坏了。同一字符串的第二个锁不会等待,但第一次释放将销毁该锁,因此第二次释放将引发错误 test.py import threading import time class TestThread(threading.Thread): def __init__(self, input): threading.Thread.__init__(self) self.input = input lock_

我正在尝试为类似的输入字符串设置锁。但是锁坏了。同一字符串的第二个锁不会等待,但第一次释放将销毁该锁,因此第二次释放将引发错误

test.py

import threading
import time

class TestThread(threading.Thread):
    def __init__(self, input):
        threading.Thread.__init__(self)
        self.input = input

        lock_wrap = "TestThread." + self.input + " = threading.Lock()"
        eval(compile(lock_wrap,'<string>','exec'))

    def run(self):
        acquire_wrap = "TestThread." + self.input + ".acquire()"
        exec(compile(acquire_wrap,'<string>','exec'))
        print("waste some time for %s" % self.input)
        time.sleep(30)
        print("%s done" % self.input)
        release_wrap = "TestThread." + self.input + ".release()"
        exec(compile(release_wrap,'<string>','exec'))

my_threads = [] 

while True:
    input = raw_input("> ") 
    if input == "end": 
        break 
    thread = TestThread(input)
    my_threads.append(thread)
    thread.start()

for t in my_threads:
    t.join()
导入线程
导入时间
类TestThread(threading.Thread):
定义初始化(自我,输入):
threading.Thread.\uuuuu init\uuuuuu(自)
self.input=输入
lock_wrap=“TestThread.”+self.input+”=threading.lock()
eval(编译(lock_wrap,,'exec'))
def运行(自):
acquire_wrap=“TestThread.”+self.input+”.acquire()
exec(编译(获取包装,,'exec'))
打印(“为%s”%self.input浪费一些时间)
时间。睡眠(30)
打印(“%s完成”%self.input)
release_wrap=“TestThread.”+self.input+”.release()
exec(编译(release_wrap,,'exec'))
我的线程=[]
尽管如此:
输入=原始输入(“>”)
如果输入==“结束”:
打破
线程=测试线程(输入)
my_threads.append(线程)
thread.start()
对于my_线程中的t:
t、 加入
结果

$ python test.py 
> foo
> waste some time for foo
bar
waste some time for bar
 > foo
> waste some time for foo
foo done
bar done
foo done
Exception in thread Thread-3:
Traceback (most recent call last):
  File "/usr/lib/python2.7/threading.py", line 552, in __bootstrap_inner
    self.run()
  File "test.py", line 19, in run
    exec(compile(release_wrap,'<string>','exec'))
  File "<string>", line 1, in <module>
error: release unlocked lock
$python test.py
>福
>浪费一些时间在foo上
酒吧
浪费一些时间去酒吧
>福
>浪费一些时间在foo上
完蛋了
酒吧
完蛋了
线程3中的异常:
回溯(最近一次呼叫最后一次):
文件“/usr/lib/python2.7/threading.py”,第552行,在引导程序内部
self.run()
运行中的文件“test.py”,第19行
exec(编译(release_wrap,,'exec'))
文件“”,第1行,在
错误:释放解锁的锁

在此应用程序中使用eval没有意义;为什么不为每个线程保留一个锁呢

class TestThread(threading.Thread):
    def __init__(self, input):
        threading.Thread.__init__(self)
        self.input = input
        self.lock = threading.Lock()

    def run(self):
        self.lock.acquire()
        print("waste some time for %s" % self.input)
        time.sleep(5)
        print("%s done" % self.input)
        self.lock.release()
您提到希望对相同的字符串使用相同的锁,但是在这种情况下,当一个字符串的锁结束时,使用相同字符串的其他线程的锁也会结束。也许如果你能更详细地解释一下你的动机,我可以提出另一个解决方案

ETA:如果您确定,对于您的特定应用程序,您希望对相同的字符串使用相同的锁,那么这将是一种方法:

LOCK_DICT = {}
LOCK_DICT_LOCK = threading.RLock()

class TestThread(threading.Thread):
    def __init__(self, input):
        threading.Thread.__init__(self)
        self.input = input

        with LOCK_DICT_LOCK:
            if self.input not in LOCK_DICT:
                LOCK_DICT[self.input] = threading.Lock()

    def run(self):
        with LOCK_DICT_LOCK:
            lock = LOCK_DICT[self.input]

        lock.acquire()
        print("waste some time for %s" % self.input)
        time.sleep(5)
        print("%s done" % self.input)        
        lock.release()

请注意,此特定版本使用全局变量,这不是理想的设计,但它比在上面的设计中使用
eval
要好得多(它还将变量保留为类属性)。当然,无论您使用什么代码,都可以将LOCK\u DICT和LOCK\u DICT\u LOCK放在一个非全局性的地方(例如,一个您称为ThreadManager的类)。

这正是我想要的。现在我只需要学习它是如何工作的,哈哈。非常感谢大卫!我很高兴能帮上忙!同样,在使用此锁之前,请确保您确实希望对多个线程使用相同的锁。