QT,在A线程中循环创建N个B线程,经测试,这N个B线程执行完毕之后不会发送finished信号,程序也不会析构它们,何解?

xiaoxiaoa2 2014-07-20 07:44:39
QT,在A线程中循环创建N个B线程,经测试
这N个B线程执行完毕之后不会发送finished信号,程序也不会析构它们,何解?

下面用伪代码表示吧,代码可能不对,但我做的程序是想这样来实现的
先构建两个线程
A class:public QThread{
public:
A:A(){
//BThread=new B; //将run()函数中的new B移动到这里来,B执行完就会正确析构
}
void run(){
while(true){
BThread=new B;
connect(BThread,SIGNAL(finished()),BThread,SLOT(deletelater()));
BThread->start();
}
}
private:
B *BThread;
}
B class:public QThread{
public:
void run()
{
qDebug()<<currentThreadId();
this->exec(); //写不写都一样
this->quit(); //写不写都一样
}
}

main{
A *a=new A;
a->start();
}


我想实现的功能是:
A线程的run函数中不断new出来B线程对像
while(true){
BThread=new B;
BThread->start();
connect(BThread,SIGNAL(finished()),BThread,SLOT(deletelater()));
}

当B线程对像执行完之后,会自动析构
但是我这种做法,它是不会自动析构的
-----------------------------------------
另外我尝试在A线程中创建QVector<B> *BVector
然后将A中创建的B线程对像放到BVector中,然后再forech这些对像,发现它们都在运行,没有结束
强制delete会告诉我这些对像在运行,BVector->item-isfinished() 发现它还在运行
也就是在A中创建的B线程对像执行start(),run()函数中的内容运行完之后,它不退出

————————————————————————————————————————

已经Google/百度搜索多次,没有发现我想实现的这种样例和解决方法
请高手帮我改一下,改成它能够自动析构,
并且我可以随意创建N个B线程对像并执行

希望各位大大,建一个这样的工程,然后测试一下,给一份可行的代码给我
非常感谢!
...全文
339 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
clz2012 2014-07-21
  • 打赏
  • 举报
回复
我也搞不懂为什么在一个子线程里调用一个exec函数,就比如一个模式对话框,对于线程而言估计就是在那死跑,quit函数一直是不会执行的
clz2012 2014-07-21
  • 打赏
  • 举报
回复
引用 9 楼 dbzhang800 的回复:
[quote=引用 8 楼 chenlingzhen 的回复:] 我也搞不懂为什么在一个子线程里调用一个exec函数,就比如一个模式对话框,对于线程而言估计就是在那死跑,quit函数一直是不会执行的
这个和子线程没关系,你在主线程里面调用事件循环也是这个效果。比如QCoreApplication::exec()/QDialog::exec()/QMenu::exec()/...[/quote] 嗯,就相当于等待事件循环,如果没有事件或信号发过来那么它会一直在那等
dbzhang800 2014-07-21
  • 打赏
  • 举报
回复
引用 8 楼 chenlingzhen 的回复:
我也搞不懂为什么在一个子线程里调用一个exec函数,就比如一个模式对话框,对于线程而言估计就是在那死跑,quit函数一直是不会执行的
这个和子线程没关系,你在主线程里面调用事件循环也是这个效果。比如QCoreApplication::exec()/QDialog::exec()/QMenu::exec()/...
dbzhang800 2014-07-21
  • 打赏
  • 举报
回复
引用 13 楼 xiaoxiaoa2 的回复:
[quote=引用 7 楼 dbzhang800 的回复:] 因为你的run()内通过exec()启动了一个while循环,所以你的run根本就没有执行完的时候(除非你调用了quit())。另外,你exec()后面的quit() 不会起作用的。 你觉得下面的代码能正常工作么? xxx = True while(xxx) { } xxx = False;
这是在A线程中执行的 我需要的就是A线程永远不要停下来 你的意思是,在A线程中new出来B线程的对象,只要A线程不结束 那么B线程永远不会结束? 另外我在B线程中添加了this->quit();是没有任何作用的[/quote] 不妨抽时间把我前面贴的blog看看,把例子都跑一遍,对你理解QThread会有好处。另外,你也需要恶补一些事件循环的知识。具体到deleteLater,你也可以看看这篇blog: http://blog.csdn.net/dbzhang800/article/details/6300025 ---------------------------------- 言归正传, 这儿举得while例子,是说的你的B线程的情况,而不是说A线程。注意:exec() 就是while循环! 其他我就不重复了,你疑惑的这些(事件循环和QThread的工作机制)都属于Qt比较底层比较基础的东西,一旦你掌握了,你会发现问题很简单,用不着乱试。
xiaoxiaoa2 2014-07-21
  • 打赏
  • 举报
回复
引用 7 楼 dbzhang800 的回复:
因为你的run()内通过exec()启动了一个while循环,所以你的run根本就没有执行完的时候(除非你调用了quit())。另外,你exec()后面的quit() 不会起作用的。 你觉得下面的代码能正常工作么? xxx = True while(xxx) { } xxx = False;
这是在A线程中执行的 我需要的就是A线程永远不要停下来 你的意思是,在A线程中new出来B线程的对象,只要A线程不结束 那么B线程永远不会结束? 另外我在B线程中添加了this->quit();是没有任何作用的
xiaoxiaoa2 2014-07-21
  • 打赏
  • 举报
回复
引用 5 楼 dbzhang800 的回复:
[quote=引用 2 楼 xiaoxiaoa2 的回复:] 不知道之前的留言你看了没,应该不是事件循环的问题 我做了一个实验,把它们的指针放到QVector中,然后等他们全部运行完之后 对QVector中的对像进行isFinished判断,发现是false的,也就是它们仍然在运行中 强制停止程序,还会出现QThread: Destroyed while thread is still running 的错误,所以应该不是事件循环的问题 另外事件循环我尝试过在多处加载this->exec,都没有用
从你这儿的描述看,你还不了解exec()是干嘛用的,所谓的事件循环,它真的是一个while循环。所以,exec() 可不是随便加的,更不是可以在随便在多处添加的。 [/quote] 我确实不太理解事件循环的用处 在上一个帖子你跟我说因为没有事件循环 我在一些地方看到用exec函数来保持程序响应,于是我尝试增加这个函数, 但增加或者不增加,都没有起到任何作用
xiaoxiaoa2 2014-07-21
  • 打赏
  • 举报
回复
引用 6 楼 dbzhang800 的回复:
[quote=引用 3 楼 xiaoxiaoa2 的回复:] 其正真的原因是: 在A线程中,创建的B线程,执行start()后,run()函数执行完之后, B线程仍然在运行 <---非常不解,不信你可以做实验看一下
不用试,在你顶楼的代码中,你的B线程内启动了事件循环,如果你没有其他的代码使之退出循环,必然是你这儿描述的结果了。[/quote] 我知道,我事实 上是不希望A线程的while循环停下来的 while的条件和循环内的条件我会做相应处理,来限制线程的数量 另外我在演示代码中说过,B线程的exec和quit两个函数, 不管添加还是 不添加,都不影响该线程是否退出 B线程都不会退出 我测试过在B线程中只添加exec或者只添加quit 在B线程run函数结束的最后一句执行一个qDebug()显示出来 这个qDebug()能显示出来,说明已经执行到末尾了 你没有测试,当然只是理论的讲,而且事实上,解决不掉我这个问题……
dbzhang800 2014-07-20
  • 打赏
  • 举报
回复
因为你的run()内通过exec()启动了一个while循环,所以你的run根本就没有执行完的时候(除非你调用了quit())。另外,你exec()后面的quit() 不会起作用的。 你觉得下面的代码能正常工作么? xxx = True while(xxx) { } xxx = False;
dbzhang800 2014-07-20
  • 打赏
  • 举报
回复
引用 3 楼 xiaoxiaoa2 的回复:
其正真的原因是: 在A线程中,创建的B线程,执行start()后,run()函数执行完之后, B线程仍然在运行 <---非常不解,不信你可以做实验看一下
不用试,在你顶楼的代码中,你的B线程内启动了事件循环,如果你没有其他的代码使之退出循环,必然是你这儿描述的结果了。
dbzhang800 2014-07-20
  • 打赏
  • 举报
回复
引用 2 楼 xiaoxiaoa2 的回复:
不知道之前的留言你看了没,应该不是事件循环的问题 我做了一个实验,把它们的指针放到QVector中,然后等他们全部运行完之后 对QVector中的对像进行isFinished判断,发现是false的,也就是它们仍然在运行中 强制停止程序,还会出现QThread: Destroyed while thread is still running 的错误,所以应该不是事件循环的问题 另外事件循环我尝试过在多处加载this->exec,都没有用
从你这儿的描述看,你还不了解exec()是干嘛用的,所谓的事件循环,它真的是一个while循环。所以,exec() 可不是随便加的,更不是可以在随便在多处添加的。
foruok 2014-07-20
  • 打赏
  • 举报
回复
引用 3 楼 xiaoxiaoa2 的回复:
[quote=引用 1 楼 dbzhang800 的回复:]
重复发帖没必要,从你这儿的代码看,主要是你还是没意识到你错在哪儿了。

引用
void run(){
while(true){
BThread=new B;
connect(BThread,SIGNAL(finished()),BThread,SLOT(deletelater()));
BThread->start();
}
}


首先,你这里面这么用while肯定不行,这要创建多少线程啊?恐怕你的系统承受不了。

其次,你这里面没有启动事件循环,deleteLater() 是不可能被执行的


其正真的原因是:
在A线程中,创建的B线程,执行start()后,run()函数执行完之后,
B线程仍然在运行 <---非常不解,不信你可以做实验看一下[/quote]
你的线程关系紊乱,应该先想好线程的作业顺序,然后结合线程环境、生命周期、quit/wait等,正确控制你的线程
xiaoxiaoa2 2014-07-20
  • 打赏
  • 举报
回复
引用 1 楼 dbzhang800 的回复:
重复发帖没必要,从你这儿的代码看,主要是你还是没意识到你错在哪儿了。
引用
void run(){ while(true){ BThread=new B; connect(BThread,SIGNAL(finished()),BThread,SLOT(deletelater())); BThread->start(); } }
首先,你这里面这么用while肯定不行,这要创建多少线程啊?恐怕你的系统承受不了。 其次,你这里面没有启动事件循环,deleteLater() 是不可能被执行的
其正真的原因是: 在A线程中,创建的B线程,执行start()后,run()函数执行完之后, B线程仍然在运行 <---非常不解,不信你可以做实验看一下
xiaoxiaoa2 2014-07-20
  • 打赏
  • 举报
回复
引用 1 楼 dbzhang800 的回复:
重复发帖没必要,从你这儿的代码看,主要是你还是没意识到你错在哪儿了。
引用
void run(){ while(true){ BThread=new B; connect(BThread,SIGNAL(finished()),BThread,SLOT(deletelater())); BThread->start(); } }
首先,你这里面这么用while肯定不行,这要创建多少线程啊?恐怕你的系统承受不了。 其次,你这里面没有启动事件循环,deleteLater() 是不可能被执行的
while(true) 这个是演示的,true变量可能换成其它控制线程数量的变量的 不知道之前的留言你看了没,应该不是事件循环的问题 我做了一个实验,把它们的指针放到QVector中,然后等他们全部运行完之后 对QVector中的对像进行isFinished判断,发现是false的,也就是它们仍然在运行中 强制停止程序,还会出现QThread: Destroyed while thread is still running 的错误,所以应该不是事件循环的问题 另外事件循环我尝试过在多处加载this->exec,都没有用
dbzhang800 2014-07-20
  • 打赏
  • 举报
回复
重复发帖没必要,从你这儿的代码看,主要是你还是没意识到你错在哪儿了。
引用
void run(){ while(true){ BThread=new B; connect(BThread,SIGNAL(finished()),BThread,SLOT(deletelater())); BThread->start(); } }
首先,你这里面这么用while肯定不行,这要创建多少线程啊?恐怕你的系统承受不了。 其次,你这里面没有启动事件循环,deleteLater() 是不可能被执行的

16,239

社区成员

发帖
与我相关
我的任务
社区描述
Qt 是一个跨平台应用程序框架。通过使用 Qt,您可以一次性开发应用程序和用户界面,然后将其部署到多个桌面和嵌入式操作系统,而无需重复编写源代码。
社区管理员
  • Qt
  • 亭台六七座
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧