【问题标题】:Joining multiple threads in any order以任意顺序加入多个线程
【发布时间】:2014-09-24 10:11:07
【问题描述】:

我有一个 std::thread 对象数组,它们以什么顺序操作以及它们重新加入主线程的顺序无关紧要。我试过使用

for(int i = 0; i < noThreads; ++i)
{
    if(threads[i].joinable())
        threads[i].join();
}

但是 似乎 让它们“按顺序”运行,当然这可能是我从线程的控制台输出发生在命令我分派它们(如线程#1的所有输出,然后是线程#2的所有输出)。我也尝试过threads[i].detach(),但我不知道每个线程的执行时间,所以我无法暂停程序,直到它们完成。

每个线程正在做的工作是:

int spawn(const char* cmd)
{
    FILE *fp = popen(cmd, "r");

    char buff[512];

    if(vFlag == 1)
    {
        while(fgets(buff, sizeof(buff), fp)!= NULL)
        {
            printf("%s", buff);
        }
    }

    int w = pclose(fp);
    if(WIFEXITED(w))
        return WEXITSTATUS(w);
    else 
        return -1;
}

正在执行的命令是"./otherApp.elf"。请记住,当前将其打印到控制台的事实将更改为输出到各种文件,我如何调度线程以便我可以让它们执行然后乱序重新加入?

【问题讨论】:

  • 1) joinable 并不像您认为的那样。 2) 执行顺序不受连接顺序的影响
  • 线程将并行执行。 join 只是表示“阻塞,直到相关线程完成”,并且您加入线程的顺序不会影响执行顺序。
  • 因此,如果我像我那样在 for 循环中运行并 join() 每个线程,它将“正确”运行?
  • @bamboon 谢谢,我不确定这只是我对执行顺序的看法还是实际的顺序变化,请澄清一下。
  • @bamboon 如果你想把它写成答案,我会接受它

标签: c++ multithreading


【解决方案1】:

执行顺序不受连接顺序的影响。所以你可以简单地循环调用join 来加入所有线程。

值得指出的第二件事是joinable 并不意味着线程是否已完成执行。详细说明见链接。

如果你真的想检查一个线程是否已经完成执行,可能还有其他方法可以做到这一点,如here 所述。

Boost 已经有扩展来等待任何或所有一组期货和testing functions 以查看线程是否已完成执行。

【讨论】:

    【解决方案2】:

    您使用的 for 循环是给您加入的顺序(不是线程执行顺序)。

    我的意思是join函数在等待线程完成时阻塞进程,所以如果你用你正在使用的for循环检查线程,你会在第一次加入时阻塞你的主进程即使(即)最后一个线程已经完成。

    如您所见i.e. herejoinable 方法的含义类似于:此线程是否已启动(或可能已完成)并且尚未加入?

    因此,如果您需要知道线程是否完成,我认为您可以使用链接到每个线程的信号量之类的东西,并在一个循环中检查其值。因此,您不会阻塞主进程,并且几乎可以按照完成顺序加入线程。

    【讨论】:

      猜你喜欢
      • 2014-08-20
      • 2017-12-22
      • 1970-01-01
      • 2016-05-15
      • 1970-01-01
      • 1970-01-01
      • 2012-01-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多