1

我有两个线程一和二。由它们各自在头文件中的类定义。我想在第一个线程启动时启动第二个线程。在第一个的构造函数中创建和启动第二个线程产生了意外的结果。我的头文件“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 ie 中显式调用两个。

int main(int argc,char* argv[])
{
     One a;
    Two b;
    a.start();
    b.start();
    a.wait();
    b.wait();
   return(0);
}

线程二的调用和处理应该由线程一来完成。

4

1 回答 1

6

我相信您可能误解了一些线程概念。听起来您想启动两个线程,然后从一个线程上下文对另一个线程上下文进行函数调用,这不是线程的工作方式。

当您启动这两个线程时,它们会相互独立地执行。他们可以共享对数据的访问,但您不能以您想要的方式将他们的执行交织在一起。如果您希望一个线程根据另一个线程的请求执行某些操作,则有两个决定两件事:

  • 使用哪种机制将请求从一个线程发送到另一个线程
  • 请求线程是否应该停止并等待“收据”,或者只是在另一个线程执行它所要求的操作时愉快地继续。

一个非常简单(而且不是很安全,这只是说明逻辑)的机制是使用两个布尔值来发出请求信号,例如:

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() 调用将不会返回,直到线程一完成互斥锁。如果两个线程都表现良好,并且在访问共享列表之前获取互斥锁,则不会发生上述同时更新,并且在两个线程都更新后列表将完全有效。

回应评论:

您不能同时启动两个线程。最接近的近似值是从 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();
}
于 2011-03-08T10:45:21.513 回答