【问题标题】:Multi-Threads inside Multi-Classes多类中的多线程
【发布时间】:2016-07-11 13:34:43
【问题描述】:

我想运行两个线程,一个用于我拥有的每个类。但我希望他们独立。例如,我有这样的事情:

class A
{
    pthread_t threadA;

    void runThreadA() { pthread_create(... arguments_here ...)};
}

class B
{
    pthread_t threadB;

    void runThreadB() { pthread_create(... arguments_here ...)};
}

目前我在内部为每个类创建并运行两个线程,但我的主要是这样的:

main()
{
    A.runThreadA();
    B.runThreadB();

    pthread_join(threadA, NULL);
    pthread_join(threadB, NULL);

    return 0;
}

如何在内部也加入两个线程,导致两个线程并行运行?

希望我能理解.. 谢谢

【问题讨论】:

  • 你不能把pthread_join放在类析构函数中吗?
  • @NathanOliver 加入析构函数不是一个好主意。 Maria 你可以使用线程池来实现所需的功能。
  • “内部加入”是什么意思?
  • @immibis 与“在内部加入”我的意思是我不想在 main() 内部调用 'pthread_join()' 函数。我希望它在类成员函数中自动发生。
  • @maria 阅读有关 RAII 的更多信息。析构函数不能轻易报告错误,也不能优雅地失败。析构函数没有返回值,抛出异常会导致应用程序的 UB/终止。 stackoverflow.com/questions/130117/…

标签: c++ multithreading class pthreads posix


【解决方案1】:

我将保留此作为答案,因为我还没有发表评论的特权,但我会尽力而为。我将解释当您说在内部加入线程时,您的意思是在类内部并且自动地,而不必在主函数中编写额外的连接行。简而言之,答案是肯定的。您可以从类内部调用 join,但这样做有些无效,原因如下。

让我们考虑这个例子(我将使用 std::thread ,因为我更喜欢它,但 pthread 的工作原理非常相似):

class1
{
    std::thread *t1;
    void DoWork1();
    void CreateThread1() { 
        t1= new std::thread(&class1::DoWork1, this)
        JoinThread1();
    }
    void JoinThread1(){
        if (t1.joinable()) {
            t1.join();
        }
    }

};

class2
{
    std::thread *t2;
    void DoWork2();
    void CreateThread2() { 
        t2= new std::thread(&class2::DoWork2, this)
        JoinThread2();
    }
    void JoinThread2(){
        if (t2.joinable()) {
            t2.join();
        }
    }
};

现在我们理论上已经完成了这个目标,每次我们调用Class1::CreateThread() 时,它都会自动加入,而无需在主线程中额外调用join()。除了我们必须记住join() 是一个阻塞函数。因此,如果我们在main() 中调用Class1::CreateThread(),那么它将阻塞,直到线程完成并加入,然后才能调用Class2::CreateThread()。所以,如果我们尝试了这种方法,很明显线程不是并行运行的,而且一开始就使用线程也没有任何好处。

在类的析构函数中调用 join() 有一个论据,但您仍需要在某个地方调用该析构函数,因此我们仍然无法获得我认为您正在寻找的相同自动化。

那个例子非常简单,但希望它显示了一些重要的东西。无论您在类中的哪个位置实现此功能以加入线程,它都会阻止您使用主线程执行其他操作,例如创建第二个线程(从而破坏线程的大部分目的),或者您将拥有无论如何,要调用这个从 main 手动加入线程的成员函数,唯一的区别是它将是类的成员函数,而不是上面示例中的成员函数。

TLDR 因为join() 是一个阻塞函数,所以必须“手动”调用它,以确保您可以从线程中获得任何好处。

【讨论】:

  • 非常感谢,您说的很明白。最后,我将线程设置为“分离”并在 main() 中创建了一个无限循环。我发现这种响应更好地满足了我的需求。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多