我想做这样的事情:
void *do_work_son(void *data)
{
mystruct *d = (mystruct*)data;
while(true)
{
// d->whatever is corrupt
}
}
void start_thread(pthread_t *mt)
{
mystruct data = ...;
pthread_create(&(*mt), NULL, do_work_son, (void *)&data);
}
int main()
{
pthread mt;
start_thread(&mt);
// do more stuff here
pthread_join(mt, NULL);
}
这个想法是在某些线程上产生的,并继续在main
中做更多的工作......然后当完成更多的工作时,等待线程完成。
它编译得很好,但data
结构在do_work_son
内被访问时被破坏了。我认为这是因为线程正在退出,即使我在main
中调用了join。如果我将pthread_{create,join}
调用都移动到start_thread,它可以正常工作,但是我的main函数被while循环阻止。这样做我疯了吗?
答案 0 :(得分:5)
我认为这是因为线程正在退出,
不,那是因为data
是start_thread()
函数中的自动变量,当start_thread()
返回时失效,因此之后使用其地址会调用未定义的行为。
要么malloc()
为它吃了一些记忆,要么让它静止,或者其他什么。只要确保它在start_thread()
的死亡中幸存下来。
答案 1 :(得分:4)
答案很简单:您传递的是局部变量的引用,然后离开范围。将它替换为在堆上分配的数据,它将像魅力一样工作
void start_thread(pthread_t *mt)
{
mystruct *data = malloc(sizeof(*data));
...;
pthread_create(mt, NULL, do_work_son, data);
}
编辑:
关于预先分配问题:
void start_thread(pthread_t *mt)
{
mystruct local_data = {...};
mystruct *data = malloc(sizeof(*data));
*data = local_data;
...;
pthread_create(mt, NULL, do_work_son, data);
}