繁体   English   中英

为什么我将 retval (void *) 传递给 pthread_exit() 的一种方法会产生意想不到的结果?

[英]Why does one of my ways of passing retval (void *) to pthread_exit() give unexpected results?

今天是我使用线程的第一天。 我很难理解为什么我无法通过以下两种方式传递 retval(类型:void *)(即,只有一种方式会给出预期的结果,如下所示)。

我将提供我的代码的简化版本:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h> 
#include <string.h>

static void *threadFunction(void *arg)
{
  printf("thread1: hello from thread...\n");
  char array_of_chars[] = "goodbye...";
  char *ptr_to_first_element_in_array_of_chars = array_of_chars;
  
  void *exitStatus_ptr;
  exitStatus_ptr = ptr_to_first_element_in_array_of_chars;

  printf("thread1: thread about to die...\n");
  //pthread_exit( exitStatus_ptr ); /** denote as Line 17 **/
  pthread_exit((void *) "goodbye..."); /** denote as Line 18 **/
}
int main(int argc, int *argv[]) //main thread
{

  pthread_t thread1;

  void *targetThread_exitStatus;
  int s; 

  s = pthread_create(&thread1, NULL, threadFunction, NULL); 

  if (s != 0) 
  {
    perror("pthread_create() error...");
  }
  
  s = pthread_join(thread1, &targetThread_exitStatus);
  
  if (s != 0)
  {
    perror("pthread_join() error...");
  }

  printf("main thread: retval from thread is: %s\n", (char*) targetThread_exitStatus);
  printf("main thread: thread about to die...\n");

  pthread_exit(NULL);

} 

当我在我的 Linux 终端上编译上述源代码时:

gcc code.c -lpthread -o code

然后执行:

./code

我得到以下输出:

thread1: hello from thread...
thread1: thread about to die...
main thread: retval from thread is: goodbye...
main thread: thread about to die...

但是,如果我在上面的第 18 行添加单行注释,并从上面的第 17 行中删除单行注释,则输出如下:

thread1: hello from thread...
thread1: thread about to die...
main thread: retval from thread is: 
main thread: thread about to die...

如您所见,retval(即,再见...)没有显示。

鉴于字符串在 C 中存储为字符数组,并且数组“衰减”到指针(即指向数组中第一个元素的指针),为什么上面的代码只产生一种传递retval 而不是另一个(即,当单行注释添加到第 18 行并从第 17 行删除时,它不会产生预期的结果)?

这段代码:

pthread_exit( exitStatus_ptr ); /** denote as Line 17 **/

将指向局部变量的指针传递给 pthread_exit。 当您想在main()中检索该值时,该指针是无效的,因为它指向threadFunction中堆栈上的某些东西 - 当pthread_join()返回时,它已被销毁。 所以你会得到未定义的行为。

pthread_exit的手册页明确提到了这一点:

retval 指向的值不应位于调用线程的堆栈上,因为该堆栈的内容在线程终止后未定义。

另一方面:

pthread_exit((void *) "goodbye..."); 

给出指向pthread_exit()的字符串文字的指针。 字符串文字在整个过程中都存在,因此在pthread_join之后在main()中使用该指针没有问题

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM