15
我有一個線程產生一些數據(一個python列表),它應該可用於一個將讀取和顯示主線程中的數據的小部件。 其實,我使用QMutex提供對數據的訪問,以這樣的方式PySide中的線程之間的通信
class Thread(QThread):
def get_data(self):
QMutexLock(self.mutex)
return deepcopy(self.data)
def set_data(self, data):
QMutexLock(self.mutex)
self.data = deepcopy(data)
def run(self):
self.mutex = QMutex()
while True:
self.data = slowly_produce_data()
self.emit(SIGNAL("dataReady()"))
class Widget(QWidget):
def __init__(self):
self.thread = Thread()
self.connect(self.thread, SIGNAL("dataReady()"), self.get_data)
self.thread.start()
def get_data(self):
self.data = self.thread.get_data()
def paintEvent(self, event):
paint_somehow(self.data)
注意,我不是在傳遞數據的emit()
,因爲它們是通用的數據(我試圖用的PyObject作爲數據類型,但雙重free()
會使程序崩潰),但我用deepcopy()
複製數據(假設數據可以像這樣複製)。 我用了一個deepcopy的(),因爲我想,一個這樣的代碼:
def get_data(self):
QMutexLock(self.mutex)
return self.data
只會複製到數據的引用(?右)和數據將被共享和返回後解鎖... 這是代碼正確嗎? 如果數據非常大(如1'000'000項目列表),我該怎麼辦?
謝謝。
P.S.我看到一些例子,如Qt Mandelbrot example或threading example with PyQt,但它們使用QImage作爲插槽中的參數。
,我認爲這裏有一個缺陷:該代碼可以正常工作,因爲slowly_produce_data()一次返回所有數據,然後分配給一個對象變量。因爲數據引用一次被設置(我認爲是安全的),所以沒有使用互斥鎖,但是如果數據是在循環中生成的,並且是按順序構建的(即不是從返回中),那麼也需要互斥鎖。 – AkiRoss 2010-11-20 22:57:04