2011-03-08 364 views
1

我有两个线程一和两个。由它们各自的类在头文件中定义。我想在第一个线程启动时启动第二个线程。在第一个产生的意外结果的构造函数中创建并启动第二个线程。 我的头文件“header.h”C++ qthread同时启动2个线程

#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); 

} 

这是我多么希望输出运行工作代码。

编辑:改变了代码,因此现在 两个线程都正确 独立

如何启动与第一线沿第二个线程,而不会在主即明确地调用两个。

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

螺纹两者的调用和处理应该由一个线程来完成..

+0

目前我所拥有的是两个独立运行的线程,它们分开启动。我想要做的是在线程启动时调用第二个线程。 – 2011-03-08 10:58:18

+0

而这没有意义。该线程在您启动时调用。即使您可以从一个线程* object *调用另一个线程* context *到另一个线程,您也无法调用 – Erik 2011-03-08 11:03:51

+0

@Erick我已更改了代码。移除一个线程上下文的调用。我试过在线程的构造函数中调用线程2,这是否是错误的?因为我似乎看不到线程的运行输出。 – 2011-03-08 11:21:02

回答

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(); 
} 
+0

如果没有适当的内存屏障或锁定,将bools设置为标记是不安全的。在Qt中,使用交叉线程信号会更好。 – bdonlan 2011-03-08 10:47:47

+0

您可能还想阅读*条件变量*。它们允许一个线程阻塞,直到某个条件由另一个线程发出信号。这是一个空的'while'循环的替代方案,它将占用不必要的CPU时间。有关详细信息,请参阅http://doc.qt.nokia.com/4.7-snapshot/qwaitcondition.html。 – 2011-03-08 10:48:08

+0

不,它不是,因此是“*非常*简单”的短语。意图是说明线程之间的通信逻辑,而不是作者想在上下文之间进行调用。 – Erik 2011-03-08 10:49:08