c ++ qthread同时启动2个线程
Posted
技术标签:
【中文标题】c ++ qthread同时启动2个线程【英文标题】:c++ qthread starting 2 threads concurrently 【发布时间】:2011-03-08 09:15:02 【问题描述】:我有两个线程一和二。由它们各自在头文件中的类定义。我想在第一个线程启动时启动第二个线程。在第一个的构造函数中创建和启动第二个线程产生了意外的结果。 我的头文件“header.h”
#ifndef HEADER
#define HEADER
#include <QtGui>
class One:public QThread
public:
One();
void run();
;
class Two:public QThread
public:
Two();
void run();
;
#endif
我的类文件“main.cpp”
#include "header.h"
#include<iostream>
using namespace std;
One::One()
/* the output just hangs at thread two and does not get to thread one run */
Two b;
b.start();
b.wait();
void One::run()
cout<<"One run\n";
int i=0;
for(;;)
i++;
cout<<"+++ "<<i<<endl;
if(i==10)
break;
sleep(3);
Two::Two()
void Two::run()
cout<<"Two run\n";
int i=0;
for(;;)
i--;
cout<<"----- "<<i<<endl;
sleep(3);
int main(int argc,char* argv[])
One a;
// Two b;
a.start();
// b.start();
a.wait();
// b.wait();
return(0);
这是我期望输出如何运行的工作代码。
编辑:现在更改了代码 两个线程都正确 独立
如何在不明确调用 main 中的两个线程的情况下与第一个线程一起启动第二个线程,即
int main(int argc,char* argv[])
One a;
Two b;
a.start();
b.start();
a.wait();
b.wait();
return(0);
线程二的调用和处理应该由线程一来完成..
【问题讨论】:
目前我拥有的是两个独立运行的线程,它们分别启动。我想要做的是在线程一个启动时调用第二个线程。 这没有意义。启动线程时调用它。您不能从一个线程 context 调用另一个线程,即使您可以从一个线程 object 调用另一个线程 @Erick 我已经更改了代码。删除对另一个线程上下文的调用。我尝试在线程一的构造函数中调用线程二,这是错误的吗?因为我似乎看不到线程的运行输出。 【参考方案1】:我相信您可能误解了一些线程概念。听起来您想启动两个线程,然后从一个线程上下文对另一个线程上下文进行函数调用,这不是线程的工作方式。
当您启动这两个线程时,它们会相互独立地执行。他们可以共享对数据的访问,但您不能以您想要的方式将他们的执行交织在一起。如果你想让一个线程根据另一个线程的请求执行某事,你有两个决定两件事:
使用哪种机制将请求从一个线程发送到另一个线程 请求线程应该停止并等待“收据”,还是在其他线程执行请求时愉快地继续。一个非常简单(并且不是很安全,这只是说明逻辑)的机制是使用两个布尔值来表示请求,例如:
Thread one starts | Thread two starts
Thread one works | Thread two loops checking a `bool DoSomething;`
Thread one sets bool DoSomething |
Thread one loops waiting for DidSomething | Thread two beeps
| Thread two sets DidSomething
Thread one continues working |
需要注意的是线程上下文之间没有“调用”。两个线程同时执行,并通过数据(两个布尔值)进行通信。
在现实世界的多线程中,您必须担心同时访问数据。什么会如果双核机器上的两个线程同时尝试将数据附加到同一个列表中,就会发生这种情况。两个线程可能会看到相同的“列表指针结尾”,都将创建一个新条目,都将更新“列表指针结尾”。但是其中一个更改会覆盖另一个更改,在最好的情况下,您会丢失一些数据和内存泄漏,在最坏的情况下,您会崩溃。
这是您使用“互斥”机制的地方:每个线程在访问诸如列表之类的共享资源之前,都会获得一个互斥锁。互斥体的构造方式是一次只有一个线程可以“拥有”它。如果线程一碰巧先获得了互斥锁,它将继续进行列表更新,然后放开互斥锁。同时,其他试图获取互斥锁的线程将简单地坐在那里,Mutex::acquire() 调用将不会返回,直到线程一完成互斥锁。如果两个线程都表现良好,并且在访问共享列表之前获取了互斥锁,则不会发生上述同时更新,并且列表将在两个线程都更新后完全有效。
回应cmets:
您不能同时启动两个线程。最接近的近似值是从 One::run: 中创建和启动 Two:
void One::run()
Two b;
b.start();
cout<<"One run\n";
int i=0;
for(;;)
i++;
cout<<"+++ "<<i<<endl;
if(i==10)
break;
sleep(3);
b.wait();
【讨论】:
如果没有适当的内存屏障或锁定,将布尔值设置为标志是不安全的。在 Qt 中,使用跨线程信号会更好。 您可能还想阅读条件变量。它们允许一个线程阻塞,直到另一个线程发出某个条件信号。它是一个空的while
循环的替代方案,它将占用不必要的 CPU 时间。详情请见doc.qt.nokia.com/4.7-snapshot/qwaitcondition.html。
不,它不是,因此是“非常简单”的短语。目的是说明线程之间的通信逻辑,而不是作者希望在上下文之间调用的逻辑。
@Erik,像这样向初学者教授有缺陷的同步协议是很危险的——他们可能会尝试在没有适当障碍的情况下实施它们,并最终创建一个损坏的程序。要么使用锁和条件变量进行教学,要么讨论障碍的重要性。
然后在One::run()
: Two b; b.start();
和One::run()
退出之前执行b.wait();
以上是关于c ++ qthread同时启动2个线程的主要内容,如果未能解决你的问题,请参考以下文章
PyQt5中多线程模块QThread解决界面卡顿无响应问题,线程池ThreadPoolExecutor解决多任务耗时操作问题