【问题标题】:why using pthread_exit?为什么使用 pthread_exit?
【发布时间】:2026-02-23 19:00:01
【问题描述】:

我正在尝试使用此示例代码找出pthread_exit 的用法:

void* PrintVar(void* arg)
 { 
   int * a = (int *) arg; // we can access memory of a!!!
    printf( "%d\n", *a); 
 } 

int main(int argc, char*argv[]) 
 { 
   int a, rc;
    a = 10; 
   pthread_t thr; 
   pthread_create( &thr, NULL, PrintVar, &a ); 

  //why do I need it here?//
  pthread_exit(&rc); /* process continues until last  
                                threads termintates */

有两件事我不太确定:

  1. 当我们使用 pthread_create 时 - 我正在传递“a”参数的地址, 但是这个参数是否被“保存”在 PrintVar 函数的“arg”下? 例如,如果我正在使用:PrintVar(void *blabla),并想从主函数传递 2 个参数:int a = 10, int b= 20 .. 我该怎么做?

  2. 为什么需要 pthread_exit?这意味着 - 等待进程结束 - 但是如果我不使用那条线,我会得到什么情况?

非常感谢!

【问题讨论】:

  • 参考第二个问题:你试过会发生什么吗?提示:在PrintVar() 的开头添加sleep(1); 并注释掉对pthread_exit() 的调用。
  • 这些是多线程的基本问题,也是相当聪明的问题。 computing.llnl.gov/tutorials/pthreads也许一本好书会帮助更多
  • @alk 我在没有睡眠的情况下使用它,它的工作方式与没有任何线程的情况相同..这就是为什么我很困惑:(我会尝试你的建议!谢谢

标签: c multithreading unix pthreads


【解决方案1】:
  1. 当我们使用 pthread_create 时 - 我正在传递“a”参数的地址,但该参数是否“保存”在 PrintVar 函数的“arg”下?

“原始”amain 中定义的那个)没有被复制,您只是传递了一个指向它的指针。

例如,如果我使用的是:PrintVar(void *blabla),并且想从主函数传递 2 个参数:int a = 10, int b= 20 .. 我该怎么做?

将这两个值放在struct 中,并将指向此类结构的指针作为参数传递给pthread_create(因此,PrintVar 将接收此类指针并能够检索这两个值)。

我的第二个问题是为什么需要 pthread_exit?这意味着 - 等待进程结束 - 但如果我不使用那条线,我会得到什么情况?

pthread_exit 终止当前线程而不终止进程,如果其他线程仍在运行;相反,从main 返回相当于调用exit,就标准而言,它应该“终止程序”(从而隐式杀死所有线程)。

现在,作为 C 标准线程不可知论(直到 C11)并支持各种 Unix 中的线程是一个相对较新的添加,取决于 libc/kernel/whatever version exit 可能会也可能不会杀死当前线程或所有线程。

不过,在当前版本的 libc 中,exit(因此从 main 返回)应该终止进程(以及它的所有线程),实际上在 Linux 上使用系统调用 exit_group

请注意,similar discussion 适用于 Windows CRT。

【讨论】:

  • 所以如果我使用 exit() 它将终止所有线程,但如果我使用 pthread_exit 它将等待哪个线程完成?正在运行的线程?意味着操作系统不能在“中间”停止线程?
  • @user1386966:如果你使用pthread_exit,它只会杀死当前线程,让其他线程运行;当最后一个线程终止时,该进程将自动终止。使用exit,您将残酷地终止所有线程。请注意,对于“普通”线程,从其入口点返回等效于调用pthread_exit;问题出在主线程上,因为从main 返回相当于调用exit
  • +1 我要补充一点,将自动存储(堆栈)变量的地址传递给线程启动例程是相当糟糕的做法——当新线程唤醒时,该堆栈可能已经消失检查它的论点。
  • @pilcrow 所说的,这不仅是糟糕的做法,而且非常危险。传递给线程函数的指针应该是动态分配的(并且它们的所有权转移给线程),或者指向全局数据。
  • @pilcrow 如果有一个pthread_join(thr)而不是pthread_exit,那么当线程检查它时假设该值会出现在堆栈上是否安全? [刚刚浏览代码并有这个疑问]
【解决方案2】:

detached 属性仅仅决定了线程终止时系统的行为;它不是 如果进程使用 exit(3) 终止(或者等效地,如果 主线程返回)。

【讨论】:

  • 欢迎来到 SO!检查问题并检查您的答案。与其说是答案,不如说是评论。请编辑或删除,因为某些 OP 可能会否决它。