我正在构建用于与数字泵进行串行通信的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"
最佳答案
因为您正在使用对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()
documentation中描述了此行为:
获取([阻止])
不带参数调用时:如果内部计数器大于
进入时为零,递减一并立即返回。如果是
进入时为零,阻塞,等待其他线程调用
release()使其大于零。这是通过适当的方式完成的
互锁,以便在阻止多个generate()调用时,
release()会唤醒其中之一。实施可能
随机选择一个,这样唤醒被阻塞线程的顺序
不应该依赖。在这种情况下,没有返回值。
在将blocking设置为true的情况下调用时,请执行与when相同的操作
调用时不带参数,并返回true。
在将阻塞设置为false的情况下调用时,请勿阻塞。如果有电话
没有参数将阻塞,立即返回false;除此以外,
执行与不带参数调用时相同的操作,并返回true。
关于python - 线程应用程序的信号量同步失败,Python,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/24150271/