QThread

PyQtに実装されてある非同期処理です。

import sys
from PyQt4 import QtCore
from PyQt4 import QtGui

class Worker(QtCore.QThread):

    mutex = QtCore.QMutex()

    def __init__(self, name = "", parent = None):
        
        QtCore.QThread.__init__(self, parent)
        self.name = name
        self.isStopped = False
        
    def run(self):
        while not self.isStopped:
            ###if not self.mutex.tryLock():
            ###    print self.name + "failed lock"
            ###    continue
            ##with QtCore.QMutexLocker( self.mutex ):
            self.mutex.lock()
            self.print_()
            self.msleep(100)
            self.mutex.unlock()
            
    def print_(self):
        print self.name, " : execution"
        
        
class Window(QtGui.QWidget):

    def __init__(self, parent = None):
        QtGui.QWidget.__init__(self, parent)
        # threads        
        self.w1 = Worker(name="thread1")
        self.w1.started.connect(self.thread_start)
        self.w1.finished.connect(self.thread_finish)
        self.w1.finished.connect(self.thread_terminated)
        self.w2 = Worker(name="thread2")
        self.w2.started.connect(self.thread_start)
        self.w2.finished.connect(self.thread_finish)
        self.w2.finished.connect(self.thread_terminated)
        # components
        start = QtGui.QPushButton("start", self)
        start.clicked.connect(self.start)
        stop = QtGui.QPushButton("stop", self)
        stop.clicked.connect(self.stop)
        hbox = QtGui.QHBoxLayout()
        hbox.addWidget(start)
        hbox.addWidget(stop)
        self.setLayout(hbox)

    def start(self):
        self.w1.isStopped = False
        self.w2.isStopped = False
        self.w1.start()
        self.w2.start()
        # It can set priority
        #self.w1.setPriority(QtCore.QThread.LowestPriority)
        #self.w2.setPriority(QtCore.QThread.HighestPriority)
       
    def stop(self):
        self.w1.isStopped = True
        self.w2.isStopped = True
        self.w1.wait()
        self.w2.wait()
        
    def thread_start(self):     print self.sender().name + "started"
    def thread_finish(self):     print self.sender().name + "finish"
    def thread_terminated(self):     print self.sender().name + "terminated"
        
def main():
    app = QtGui.QApplication(sys.argv)
    ex = Window()
    ex.show()
    sys.exit(app.exec_())    
    
if __name__ == '__main__':
    main()

Startボタンでスレッドを起動させ、Stopボタンで停止します。
排他処理をしてるので、コンソールに正しく関数単位の内容が表示されます。
QMutexかQMutexLockerで排他処理を行います。
QMutexLockerはコンストラクタでlockしてデストラクタでunlockするクラスです。なのでwith文が使用できます。
with文を使わなくても使用できますが、unlockするタイミングはQMutexLockerインスタンスが生成された関数から抜けたときになりますので、
おとなしくwith文使うのがいいですね。ローカル変数の寿命whileとかforのスコープはではなく、関数スコープなので。ちょっとはまってしまった。
tryLockは呼び出された直後にすぐ処理を返すlock関数です。
すでにロックされていたら即falseを返し、されていなかったらロックしてTrueを返します。