我目前正在試圖瞭解Qt中的信號和插槽如何與線程行爲。Qt的信號和插槽行爲與多線程的問題
我試圖運行一個小型試驗用下面的代碼:
class Worker : public QObject{
Q_OBJECT
public:
Worker(int _value){value = _value;}
~Worker(){};
int value;
public slots:
void changeValue(int newValue){value = newValue;}
void doWork(){
while(1){
_sleep(500);
std::cout << "Value is " << value << std::endl;
if(value == 0)break;
}
emit finished();
}
signals:
void finished();
};
class Manager : public QObject{
Q_OBJECT
public:
Manager(){}
~Manager(){};
signals:
void modifiedValue(int value);
public:
void changeTheValue(int value){emit modifiedValue(value);}
};
基本上,工人在一段時間顯示其value
構件每一次,並有一個槽與該修改值的函數。
當調用changeTheValue
時,管理器的唯一目的是發出帶有新值的信號,該信號映射到修改value
成員的Worker中的插槽。
然後,我讓我的Worker
一流的工作在一個線程方式如下:
QThread myThread;
Worker myWorker(10);
Manager manager;
myWorker.moveToThread(&myThread);
QObject::connect(&myThread, SIGNAL(started()), &myWorker,SLOT(doWork()));
QObject::connect(&myWorker, SIGNAL(finished()), &myThread, SLOT(quit()));
QObject::connect(&myWorker, SIGNAL(finished()), &myWorker, SLOT(deleteLater()));
QObject::connect(&myThread, SIGNAL(finished()), &myThread, SLOT(deleteLater()));
QObject::connect(&manager, SIGNAL(modifiedValue(int)),
&myWorker, SLOT(changeValue(int)));
myThread.start();
for(int i = 1; i < 10 ; i++){
_sleep(1000);
manager.changeTheValue(i);
}
manager.changeTheValue(0);
但沒有任何反應。該值似乎沒有改變:輸出顯示十二行Value is 10
。
我不明白的是,爲什麼信號/插槽映射Manager::modifiedValue
和Worker::changeValue
似乎不工作?僅僅是因爲線程當前正在運行doWork()
的循環?對插槽的呼叫最終會在哪裏結束(排隊,丟棄,其他)?
我無法找到更多關於信號/插槽機制如何與線程一起工作的信息(我只找到this thread,它解釋了哪個線程的調用堆棧對插槽的調用結束了,但答案中提供的鏈接似乎過時了,導致Qt 5回家)。
要總結的問題:
- 爲什麼調用修改該值什麼都不做了卡槽?
- 是否有可能使這項工作(在必要時增加線程安全性)以及如何?
我希望你有[RTFM](http://qt-project.org/doc/qt-4.8/threads-qobject.html#signals-and-slots-across-threads)。 – rubenvb
不幸的是,這並不能回答我的問題。我知道QObject及其子類的'線程不安全',並且信號和插槽之間的連接默認情況下適用於上下文(自動地在同一線程中的對象之間直接連接,或者在不同對象之間的排隊連接線程),但感謝您的鏈接! – JBL