阻止主线程等待其子线程

时间:2015-12-25 21:29:18

标签: c++ multithreading stdthread

所以我有这个课程:

class foo {
public:
        foo() { };
        void me1() const {
            while(1) {
                std::lock_guard<std::mutex> ldock(m);
                std::cout << 0;
            }
        }
        void me2() const {
            while(1) {
                std::lock_guard<std::mutex> ldock(m);
                std::cout << 1;
            }
        }
private:
    std::mutex m;
};

现在我想在两个不同的线程中运行这两个方法,我这样做:

int main() {

    foo myfoo;

    std::thread firstThread(&foo::me1, &myfoo);
    std::thread secondThread(&foo::me2, &myfoo);

    firstThread.detach();
    secondThread.detach();

    //while(1) { }

    return 0;
}

我不想等待这两种方法中的任何一种方法完成,它们会同时运行直到主线程被杀死。

在主线程结束时是否可以使用某种无限循环? (如评论while(1) {})。

或者我应该打电话给某种sleep函数吗?

3 个答案:

答案 0 :(得分:3)

您需要在exit conditionfoo::me1()中定义foo::me2()。如果您不知道该怎么做,那

sleep(/*number of seconds you want your program to run*/ );

会做得很好。

如果你定义一个终止条款,那么强力就可以了 暴露像原子的东西:

class foo {
public:

std::atomic<int> me1done = false;
std::atomic<int> me2done = false;

        foo() { };
        void me1() {
            while(/* need exit condition here*/) {
                std::lock_guard<std::mutex> ldock(m);
                std::cout << 0;
            }
            me1done = true;
        }
        void me2() {
            while(/*need exit condition here*/) {
                std::lock_guard<std::mutex> ldock(m);
                std::cout << 1;
            }
            me2done = true;
        }


private:
    std::mutex m;

};

然后你可以通过每x秒轮询一次检查主。

int main(void)
{
// start your threads and detach

foo myfoo;

std::thread firstThread(&foo::me1, &myfoo);
std::thread secondThread(&foo::me2, &myfoo);

firstThread.detach();
secondThread.detach();

while( not (myfoo.me1done and myfoo.me2done ) )
{
sleep( /* some time */);
}

return 0;
}

如果您想要更详细,则必须使用condition variables

答案 1 :(得分:2)

如果你想确定两个线程是否已经完成,那么在退出主线程之前,实际上detach()线程而是join()它们。也就是说,你将启动两个线程并且它们将同时运行,并且一旦开始,只需join()。当然,这假定线程会终止。

有效地使用detach() ed线程意味着您永远无法确定它是否已完成。这通常很少有用,我认为将detach()添加到std::thread是一个错误。但是,即使使用detach() ed线程,您也可以识别何时在没有繁忙等待的情况下实现目标。为此,您需要设置适当的变量来指示完成或进度,并使其受std::mutex保护。然后,wait()上的主线程std::condition_variable将在完成/进度更新时由相应线程获得notify_once(),这将在合理的时间间隔内完成。一旦所有线程都表明它们已完成或已达到合适的目标,main()线程就可以完成。

单独使用计时器通常不是一个好方法。线程之间的信令通常是优选的,并且倾向于创建响应更快的系统。您仍然可以使用wait()的定时版本(例如,wait_until()wait_for()),例如,在怀疑某个挂起或超时的线程时发出警告。

答案 2 :(得分:0)

空无限循环,因为while(1) { }是UB。

在内部添加睡眠是可以的。

要无限运行foo::me1 / foo::me2,您还有其他几种选择:

int main()
{
    foo myfoo;

    std::thread firstThread(&foo::me1, &myfoo);
    std::thread secondThread(&foo::me2, &myfoo);

    firstThread.join();  // wait infinitely as it never ends.
    secondThread.join(); // and so never reach 
}

或者只是使用主线程来完成一项工作:

int main()
{
    foo myfoo;

    std::thread firstThread(&foo::me1, &myfoo);
    myfoo.me2(); // work infinitely as it never ends.

    firstThread.join(); // and so never reach
}