之前没有注意到qt的QThread 的MoveToThread以及线程消息的归属问题。
先注意以下两点
1所有能够接受和发送消息的class必须存在有消息循环的线程环境中。
2对象的消息处理默认环境是是存在于创建这个对象的线程环境中的。
对于第二点如何理解
比如
subthread::subthread()
{
connect(this,sigA,this,slotA);
}
subthread::run()
{
printf tid
exec();
}
void slotA(){
printf 线程id
}
UI_thread()
{
psub=new subthread();
psub->start()
Sleep(5000)
emit psub->sigA
}
在ui线程中创建了一个线程psub,运行这个线程,等待5s线程运行了以后。执行emit psub->sigA
执行 slotA函数
此时打印的线程id应该是 UI_thread的线程。
因为new的这个行为是在UI线程中执行的,所以默认的消息循环是属于UI线程的。因此在slotA中执行的操作是属于UI线程环境中的。
明显run中的id是subthread的id.此时如果有run中和slotA中同时操作一个变量,那么就会出现同步问题。
如果需要slotA中的环境在subthread中执行。那么就用到MoveToThread (this)。这里的this是psub。
object->MoveToThread(threadA)表示,将当前object对象的亲和性归属到ThreadA中。也就是让threadA来处理object的消息循环,
我们只需要在subthread的构造函数中添加
this->MoveToThread(this)。 表示让subthread对象使用自己的消息处理线程。这样就可以了。