0

我已经完成了以下代码。

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

struct foo
{
   int a;
   int b;
};

void* thread_func1(void *arg)
{
   struct foo *temp = (struct foo*)malloc(sizeof(struct foo));

   temp->a = 10;
   temp->b = 20;

   pthread_exit(temp);
}

void* thread_func2(void *arg)
{
   pthread_exit((void*)100);
}

int main()
{
   pthread_t tid1, tid2;
   int err;
   struct foo *f;
   void *ret;

   err = pthread_create(&tid1, NULL, thread_func1, NULL);
   err = err | pthread_create(&tid2, NULL, thread_func2, NULL);

   if(err != 0)
   {
      perror("pthread_create()");
      exit(-1);
   }

   err = pthread_join(tid1, (void**)&f);
   if(err != 0 )
   {
      perror("pthread_join1");
      exit(-1);
   }

   printf("a = %d, b = %d\n", f->a, f->b); //Line1

   err = pthread_join(tid2, &ret);
   if(err != 0 )
   {
      perror("pthread_join2");
      exit(-1);
   }

   printf("ret = %d\n", *(int*)ret); //Line2

   return 0;

}

我在 Line2 上遇到分段错误。Line2有什么问题

如果我将 Line2 修改为

printf("ret = %d\n", (int)ret);

没有分段错误,它打印正确的值(即 100)。我不明白为什么修改有效。我相信我对双指针的使用有错误的概念。我想纠正它。

分段错误的原因是什么以及为什么修改有效?

4

4 回答 4

3

那是因为您返回的是实际整数,而不是指针,而是将其作为指针访问。

于 2012-06-07T09:57:36.260 回答
2

您从线程返回一个数字。在第一个线程中,该数字是struct foo *. 因此,如果你说

pthread_join(tid1, &ret);

然后ret将包含该指针(不是双指针)。

同样,在第二种情况下,100即使您将其视为void *. 尽管如此,价值仍然存在100

因此,当你写

pthread_join(tid2, &ret);

ret将包含100,它不是一个指针,而只是一个整数。这就是为什么您也应该将其转换为int.

您遇到分段错误的原因是您将其100视为一个int *然后尝试取消引用它。

于 2012-06-07T09:59:49.440 回答
1

这是因为您试图取消引用地址为 100 的指针。

与其查看返回值,不如在 thread_funcs 中传递一个指向要分配的指针?也就是说,使用 thread_func1() 和 thread_func2() 的“void *arg”参数

像这样:

void* thread_func1(void *arg)
{
   struct foo **fooPtrPtr = (struct foo**) arg;
   *fooPtrPtr = (struct foo*)malloc(sizeof(struct foo));

   ...
}

void* thread_func2(void *arg)
{
   int *intPtr = arg;
   *intPtr = 100;
   ...
}

int main()
{
   pthread_t tid1, tid2;
   int err;
   struct foo *f;
   int ret;

   err = pthread_create(&tid1, NULL, thread_func1, &f);
   err = err | pthread_create(&tid2, NULL, thread_func2, &ret);
   ...
   printf("a = %d, b = %d\n", f->a, f->b); //Line1
   ...
   printf("ret = %d\n", ret); //Line2
   ...
}
于 2012-06-07T09:57:50.330 回答
1

pthread_exit((void*)100);导致整数100成为线程的退出状态。它只是滥用类型转换,所以这void*就是它的类型。如果要检索此值,则还必须在主线程中使用相同的类型转换滥用:

int ret;
err = pthread_join(tid2, (void**) &ret);
// here you can work with ret as with any other integer

我还建议您使用return而不是pthread_exit. 另请注意,通过 using 动态分配的内存malloc应通过调用free. 而这里的返回值类型转换malloc是多余的,可以省略。

这个问题也可以帮助你:Close a thread when done with it

于 2012-06-07T10:03:33.980 回答