在转换后将结构传递给pthread_create,未定义的值?

时间:2012-08-20 12:00:27

标签: c pointers struct pthreads

我试图将一个结构作为参数传递给pthread_create,似乎得到了一些奇怪的结果。

struct有两个成员,第一个是int,第二个是函数指针:

typedef struct
{
  int num;
  void (*func)(int);
} foo_t;

我试图在结构中使用的函数:

void myfunc(int mynum)
{
   printf("mynum: %d\n", mynum);
}

这是我将传递给我的线程的结构的声明:

foo_t f;
f.num = 42;
f.func = &myfunc;

对pthread_create的调用:

pthread_create(&mythread, NULL, mythreadfunc, &f);

最后,我的线程功能:

void mythreadfunc(void *foo)
{
   foo_t f = *(foo_t *)foo;
   printf("num: %d\n", f.num); // Prints: num: 32776 (undefined?)
   (*f.func)(f.num);  // Segfaults (again, undefined?)
...

似乎mythreadfunc中的强制转换似乎不起作用,我无法弄清楚原因。有什么建议?感谢。

2 个答案:

答案 0 :(得分:1)

您正在通过引用传递foo_t f。如果您要从f - 调用函数或其他地方更改pthread_create,例如,保留相应的范围将从堆栈中删除/删除f,那么您在线程中的引用是(很可能)无效。至少你不应该再访问它了。

使用带有动态分配变量的指针。

虽然我无法证明您所提供的代码会发生这种情况。

修改

指针用于存储对象/变量的地址。在C/C++中,您可以指向动态分配的内存段。为此查询malloc/ new。您可以使用指针执行所谓的dereferencing并访问对象/变量本身。

您可以传递每个值的指针,这意味着您不会传递对象/变量本身,而是传递RAM中对象/变量的地址(=位置)。动态分配的varialbes / object的内存管理由程序员负责,因此当指针范围结束时,不会删除对象,只删除存储地址的指针。

答案 1 :(得分:1)

Papergay的答案肯定是一个解决方案,但如果你想避免动态分配,你可以使用的另一种方法就是使用同步。我最喜欢的方法是在结构中放置一个初始值为零的信号量,让父节点等待信号量,子节点在读完结构中的值后发布信号量。