我目前正在试图了解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