我是线程新手,使用pthread_join时遇到问题。

这是我的代码:

int             create_threads(t_lemin *lem)
{
  int           i;
  pthread_t     **threads;
  int           j;
  void          *ret;
  t_tree        *tmp;

  j = -1;
  printf("starting algo\n");
  threads = xmalloc(sizeof(pthread_t));
  i = count_leaf(lem->start);
  tmp = lem->start;
  printf("%d\n", tmp->visited[0]);
  while (++j != i)
    {
      tmp->leaf[j]->thread_nbr = j;
      pthread_create(threads[j], NULL, find_way_out, tmp->leaf[j]);
      usleep(100);
    }
  i = -1;
  while (++j != i)
    (void)pthread_join (*threads[j], &ret);
  //printf("%d\n", *((int*)ret));
    return (0);
}


我的一个线程完成了他的工作,第二个线程完成后,我遇到了Segmentation Fault。
我的函数find_way_out返回pthread_exit((void *)j);或pthread_exit(0);
其中j是整数指针。
您是否知道它的来源?

谢谢 !

最佳答案

问题在于,您应该将指向实际pthread_t变量的指针作为pthread_create的第一个参数传递,作为模拟按引用传递的方式,然后pthread_create将初始化该对象。

由于传递了未初始化的指针,因此当pthread_create取消引用指针时,将具有undefined behavior。当您尝试取消引用pthread_join调用的指针时,也将拥有它。

甚至更糟,因为您只为一个pthread_t对象分配空间,所以您将超出“数组”的范围。

然后对于pthread_join循环,您将使j是一个小的正数,而i是一个负数,这意味着您的循环将迭代很多,因为必须迭代直到j溢出并变为负数然后继续循环直到j等于-1

相反,我建议这些更改:


pthread_t对象使用可变长度数组
将数组的“大小”保存在一个不变的变量中
最后,使用for循环代替


就像是

size_t count = count_leaf(lem->start);
pthread_t threads[count];

for (size_t i = 0; i < count; ++i)
    pthread_create(&threads[i], ...);

...

for (size_t i = 0; i < count; ++i)
    pthread_join(threads[i], NULL);

关于c - 调用pthread_join之后出现SegFault,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/29878171/

10-11 16:46