簡體   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