c++ qthread同时启动2个线程

发布于 2024-10-20 22:59:01 字数 1506 浏览 3 评论 0原文

我有两个线程一和二。由头文件中各自的类定义。我想在第一个线程启动时启动第二个线程。在第一个线程的构造函数中创建并启动第二个线程会产生意外的结果。 我的头文件 "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);
}

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

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..

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

一曲琵琶半遮面シ 2024-10-27 22:59:01

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

当您启动这两个线程时,它们彼此独立执行。它们可以共享对数据的访问,但您无法按照您想要的方式交织它们的执行。如果您希望一个线程根据另一个线程的请求执行某些操作,则需要两个人决定两件事:

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

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

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              | 

需要注意的是没有“调用”在线程上下文之间。两个线程同时执行,并使用数据(两个布尔值)进行通信。

在现实世界的多线程中,您必须担心同时访问数据的问题。例如,如果双核计算机上的两个线程同时尝试将数据附加到同一列表,会发生什么情况。两个线程可能会看到相同的“列表末尾指针”,两个线程都会创建一个新条目,两个线程都会更新“列表末尾指针”。但其中一项更改将覆盖另一项更改,在最好的情况下,您会丢失一些数据和内存泄漏,在最坏的情况下,您会崩溃。

这就是使用“互斥”机制的地方:每个线程在访问列表等共享资源之前,都会获取一个互斥体。互斥体的构造方式使得一次只有一个线程可以“拥有”它。如果线程一碰巧首先获取互斥体,它将继续进行列表更新,然后释放互斥体。与此同时,尝试获取互斥体的其他线程将只是坐在那里,直到线程 1 完成互斥体的操作后,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();
}

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();
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文