【问题标题】:pthread - How to start running a new thread without calling join?pthread - 如何在不调用 join 的情况下开始运行新线程?
【发布时间】:2011-09-05 07:00:06
【问题描述】:

我想从主线程开始一个新线程。我不能使用 join,因为我不想等待线程退出然后继续执行。
基本上我需要的是 pthread_start(...) 之类的东西,但是找不到。

编辑:
由于所有答案都建议 create_thread 应该启动线程,问题是在下面的简单代码中它不起作用。下面程序的输出是“主线程”。似乎子线程从未执行过。知道我哪里错了吗?
在 Fedora 14 GCC 版本 4.5.1 上编译和运行

void *thread_proc(void* x)
{
   printf ("sub thread.\n");
   pthread_exit(NULL);
}


int main()
{
    pthread_t t1;
    int res = pthread_create(&t1, NULL, thread_proc, NULL);
    if (res)
    {
        printf ("error %d\n", res);
    }

    printf("main thread\n");
    return 0;
}

【问题讨论】:

  • 程序的输出是什么?可能的原因见user396672的回答(主线程结束,os在子线程完成之前杀死所有线程)。
  • 如果您从main 发送return,您的程序将终止。改为在主线程中调用pthread_exit
  • 或者只是添加 pthread_join(t1, NULL);返回 0 之前;

标签: c++ c linux multithreading pthreads


【解决方案1】:

只需创建将分离属性设置为 on 的线程。为此,您可以在创建线程后调用pthread_detach,也可以在创建线程之前调用pthread_attr_setdetachstate

当一个线程被分离时,父线程不必等待它,也无法获取它的返回值。

【讨论】:

    【解决方案2】:

    当您create 时,线程会自动启动。

    【讨论】:

    • 另外,它不保证一个完整的答案,但如果你不加入你创建的线程,你的程序将在他们做任何事情之前退出,因为主线程中的执行将继续。
    【解决方案3】:

    您不需要调用 pthread_create 吗?

    static void *thread_body(void *argument) { /* ... */ }
    
    int main(void) {
        pthread_t thread;
        pthread_create(&thread, NULL, thread_body, NULL);
        /* ... */
    

    【讨论】:

      【解决方案4】:

      启动线程的函数是pthread_create,不是 pthread_join。只有在准备好等待时才使用pthread_join, 并重新同步,如果您分离线程,则无需使用 它根本没有。您也可以从其他线程加入。

      在退出之前(通过调用exit 或从main 返回), 您必须确保没有其他线程正在运行。一种方式(但不是 唯一的)要做到这一点是通过加入你所有的线程 已创建。

      【讨论】:

      • +1 实际上,您没有必须在退出之前等待其他线程。调用 exit() 将自动终止所有线程。不过,如果您想优雅地终止,您可能需要使用 pthread_barrier 或 pthread_join。
      • @Klas Lindback 调用exit() 将终止整个进程,这当然会终止所有线程。但这不是一个瞬间的过程。 exit 执行的步骤很长,并且终止线程接近它们的末尾。与此同时,静态变量的析构函数已经被调用,内存结构(包括malloc?的那些)被清理等等等等。与此同时,其他线程继续运行,最终使用已经被清理的资源。 C++11 也增加了限制。
      • 噢噢噢,我现在明白了。想知道如果我打电话给pthread_detach,为什么我的线程没有被执行......我现在明白它是如何工作的。这实际上对永远不会退出的守护进程/服务有好处(至少在理论上)。谢谢!
      【解决方案5】:

      join 调用等待线程终止并退出。

      如果您希望主线程在子线程执行时继续执行,请不要调用join:子线程将与主线程同时执行...

      【讨论】:

      • 是的。是什么让您认为不调用 join() 是不标准的? (老实说,你还是应该在主线程结束时调用join(),以确保所有子线程在退出应用程序之前终止)
      • 你认为我可以简单地在类的析构函数中调用 detach() 吗?
      • 这取决于设计。你可以这样做,但它会让线程自己运行:这是一种我不喜欢的资源泄漏。 (但我们偏离了原来的问题)
      【解决方案6】:

      代码的行为取决于调度程序;可能主程序在创建的线程中的 printf 执行之前退出。我希望 main() 末尾的简单 sleep(some_seconds) 会导致线程输出出现:)

      【讨论】:

      • 谢谢@user396672 这确实是问题所在。我选择詹姆斯的答案,因为它与原始问题相匹配,但至少我给了你一个赞成票:)
      • 这是正确答案。在从 main() 返回之前等待生成的线程运行的正确解决方案是在返回之前调用 pthread_join(t1, NULL)。 pthread_create() 不保证线程一返回就开始运行。此外,实际调度线程之前的时间是不确定的。要么你用一个条件变量表示生成的线程完成了它的工作,要么你等待。
      【解决方案7】:

      你需要在man()的最后调用pthread_exit,这会导致main等待其他线程启动和退出。 或者你可以显式调用 pthread_join 来等待新创建的线程

      否则,当 main 返回时,进程被杀死,它创建的所有线程都将被杀死。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-04-13
        相关资源
        最近更新 更多