我正在构建一个用于与数字泵进行串行通信的GUI应用程序。我陷入了用于从中获取信息的更新机制。使用QTimer(来自PySide模块)每5秒调用 update_values 方法,但用户可以通过调用相同的方法专门订购更新。出于这个原因,我只想在update_values代码上运行一个线程。但是,当使用多个线程随意进入信号量块时,这似乎无法使用信号量或锁定:
self.update_sema = threading.Semaphore(value=1)
... ...
def update_values(self, initialize = False):
"""This is the parameters update method."""
self.update_sema.acquire(False)
print "ENTERED THE SEMAPHORE"
self.update_thread = threading.Thread(\
target = self.actual_update_method,\
args = (initialize,))
self.update_thread.start()
def actual_update_method(self, initialize):
# reading info mechanism
self.status["absolute_pos"] = self.send_Command('?', 10)[3:]
self.status["actual_pos"] = self.send_Command('?4', 10)[3:]
self.status["starting_vel"] = self.send_Command('?1', 10)[3:]
self.status["top_vel"] = self.send_Command('?2', 10)[3:]
self.status["cutoff_vel"] = self.send_Command('?3', 10)[3:]
self.status["backlash_steps"] = self.send_Command('?12', 10)[3:]
self.status["fluid_sensor"] = self.send_Command('?22', 10)[3:]
self.status["buffer_status"] = self.send_Command('?F', 10)[3:]
# These must be asked only once, at the initialization phase
if initialize:
#print "version set as well!"
self.status["version"] = self.send_Command('?&', 10)[3:]
self.status["checksum"] = self.send_Command('?#', 10)[3:]
self.update_sema.release()
print "EXITED THE SEMAPHORE"
答案 0 :(得分:2)
因为您正在使用对acquire
的非阻止调用(使用acquire(blocking=False)
),所以如果您确实获得了信号量,则需要确保只继续使用该方法,就像这样:
def update_values(self, initialize = False):
"""This is the parameters update method."""
if self.update_sema.acquire(False):
print "ENTERED THE SEMAPHORE"
self.update_thread = threading.Thread(\
target = self.actual_update_method,\
args = (initialize,))
self.update_thread.start()
中描述了此行为
获取([阻挡])
不带参数调用时:如果内部计数器大于 进入时为零,将其减1并立即返回。如果是 在进入,阻止,等待直到某个其他线程调用时为零 release()使其大于零。这是适当的 互锁,以便在多个acquire()调用被阻止时 release()将完全唤醒其中一个。实施可能 随机选择一个,因此被阻止的线程被唤醒的顺序 不应该依赖。在这种情况下没有返回值。
当使用blocking设置为true调用时,请执行与when相同的操作 不带参数调用,返回true。
当阻止设置为false时调用,请勿阻止。如果打电话 没有参数会阻塞,立即返回false;除此以外, 做与没有参数调用时相同的事情,并返回true。