c ++ qthread并发启动2个线程 [英] c++ qthread starting 2 threads concurrently

查看:618
本文介绍了c ++ qthread并发启动2个线程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



  #ifndef HEADER 
#define HEADER
#include< QtGui>
class One:public QThread
{
public:
One();
void run();

};

class 2:public QThread
{
public:
Two();
void run();
};
#endif

我的类文件main.cpp

  #includeheader.h
#include< iostream>
using namespace std;

一个:: One()
{
/ *输出只是挂在线程二,不能线程一次运行* /
两个b;
b.start();
b.wait();

}
void One :: run()
{
cout<<One run\\\
;
int i = 0;
for(;;)
{

i ++;
cout<<+++<< i<< endl;
if(i == 10)
break;
sleep(3);
}
}

Two :: Two()
{

}
void Two :: run b $ b {

cout<<Two run\\\
;
int i = 0;
for(;;)
{

i--;
cout<<-----<< i<< endl;
睡眠(3);
}
}
int main(int argc,char * argv [])
{
一个;
// Two b;
a.start();
// b.start();
a.wait();
// b.wait()
return(0);

}

这是我期望输出的工作代码跑。


编辑:更改代码,以便现在
两个线程正确
独立



如何在第一个线程中启动第二个线程,而不在主线程中显式调用两个线程 $ b



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




线程二的调用和处理应该是

我相信你可能误解了一些线程概念。它听起来像你想要启动两个线程,然后从一个线程上下文做一个函数调用到另一个线程上下文,这不是线程如何工作。



当你启动这些两个线程,它们彼此独立地执行。他们可以共享对数据的访问,但是你不能以你想要的方式交织他们的执行。如果你想要一个线程根据请求执行某事,你有两个决定两件事情:




  • 从一个线程到另一个线程

  • 请求线程是否应该停止并等待收据,或者只是快乐地继续,而其他线程执行请求。



很简单(并不是很安全,这只是说明逻辑)机制,将使用两个bool以表示请求,例如:

 线程一开始|线程二开始
线程一工作|线程两个循环检查`bool DoSomething;`
线程一集bool DoSomething |
线程一个循环等待DidSomething |线程两声蜂鸣
|线程两套DidSomething
线程一继续工作|

注意的事情是线程上下文之间没有调用。这两个线程同时执行,并通过使用数据(两个bool)进行通信。



在现实的多线程中,你必须担心同时访问数据。什么会例如。如果两个线程,同时在双核机器上,试图将数据附加到同一个列表。两个线程可以看到相同的列表指针结束,两者都将创建一个新条目,两者都将更新列表指针结束。但其中一个更改将覆盖另一个,在最好的情况下,你会有一些丢失的数据和内存泄漏,在最坏的情况下,你会崩溃。



这是您使用互斥机制的地方:每个线程在访问列表之前的共享资源时都会获取互斥锁。互斥体以这样的方式构造,使得每次只有一个线程可以拥有它。如果线程一碰巧获取互斥体,它将继续做它的列表更新,然后放弃互斥体。在此期间,其他线程尝试获取互斥体将简单地坐在那里,Mutex :: acquire()调用将不会返回,直到线程一完成互斥体。如果两个线程的行为都很好,并且在访问共享列表之前获取了互斥体,上述同时更新将不会发生,并且在两个线程更新后,列表将完全有效。



响应注释:



您不能同时启动两个线程。最接近的是在一个:: run内创建和启动Two:

  void One :: run $ b {
Two b;
b.start();
cout<<One run\\\
;
int i = 0;
for(;;)
{

i ++;
cout<<+++<< i<< endl;
if(i == 10)
break;
sleep(3);
}
b.wait();
}


I have two threads One and Two. defined by their respective classes in the header file.I want to start the second thread when the first thread is started. creating and starting the second thread in the constructor of the first produced unexpected result. my header file "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

my class file "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);

}

This is the working code of how i expect the output to run.

Edit: changed the code so that now both the threads are properly independent

How do i start the second thread along with the first thread, without explicitly calling two in main i.e .

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

The invoking and handling of thread two should be done by thread one..

解决方案

I believe you've perhaps misunderstood some threading concepts. It sounds like you want to start two threads, then from one thread context make a function call to another thread context, which is not how threads work.

When you start these two threads, they execute independently of each other. They can share access to data, but you can't intertwine their execution the way you seem to want to. If you want one thread to perform something on request of another, you have two decide two things:

  • Which mechanism to use for signaling the request from one thread to the other
  • Whether the requesting thread should stop and wait for a "receipt" or just happily continue while the other thread does what it was asked to.

A very simple (and not really safe, this is just illustrating the logics) mechanism for doing this would be using two bools to signal a request, e.g:

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              | 

The thing to notice is that there's no "calls" in between thread contexts. The two threads execute simultaneously, and communicate by using data (the two bools).

In real world multithreading, you have to worry about simultaneous access to data. What would e.g. happen if two threads, at the same time on a dual-core machine, tried to append data to the same list. Both threads may see the same "end of list pointer", both would create a new entry, both would update the "end of list pointer". But one of the changes will overwrite the other, and in best case you'd have some lost data and a memory leak, in worst case you'd have a crash.

This is where you use a "mutual exclusion" mechanism: each thread will, before accessing such a shared resource as the list, get hold of a mutex. A mutex is constructed in such a way that only one thread at a time can "own" it. If thread one happens to acquire the mutex first, it'll proceed to do its list update, and then let go of the mutex. In the meantime, the other threads attempt to acquire the mutex will simply sit there, the Mutex::acquire() call will not return until thread one is done with the mutex. If both threads behave nicely, and acquire the mutex before accessing the shared list, the simultaneous update described above will not happen, and the list will be perfectly valid after both threads have updated it.

In response to comments:

You cannot start the two threads simultaneously. The closest approximation would be to create and start Two from within One::run:

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

这篇关于c ++ qthread并发启动2个线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆