用于线程应用程序的信号量同步失败,Python

时间:2014-06-10 20:27:47

标签: python multithreading synchronization pyside semaphore

我正在构建一个用于与数字泵进行串行通信的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"

1 个答案:

答案 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()

documentation

中描述了此行为
  

获取([阻挡])

     

不带参数调用时:如果内部计数器大于   进入时为零,将其减1并立即返回。如果是   在进入,阻止,等待直到某个其他线程调用时为零   release()使其大于零。这是适当的   互锁,以便在多个acquire()调用被阻止时   release()将完全唤醒其中一个。实施可能   随机选择一个,因此被阻止的线程被唤醒的顺序   不应该依赖。在这种情况下没有返回值。

     

当使用blocking设置为true调用时,请执行与when相同的操作   不带参数调用,返回true。

     

当阻止设置为false时调用,请勿阻止。如果打电话   没有参数会阻塞,立即返回false;除此以外,   做与没有参数调用时相同的事情,并返回true。