C 将普通数据传递到pthread void*
pthread函数采用void*参数。如何发送普通结构而不是指针 我想向一个pthread函数发送一个非指针结构C 将普通数据传递到pthread void*,c,pthreads,C,Pthreads,pthread函数采用void*参数。如何发送普通结构而不是指针 我想向一个pthread函数发送一个非指针结构 我还想发送一个指向void*函数的指针,这是如何实现的?可以向void*函数发送任何指针吗?不可能;你必须发送一个指针。但是,void*可以指向任何东西。如果您的结构变量被调用为foo,您只需将其作为(void*)&foo传递,并且在函数内部,您可以使用struct foo*fooPtr=(struct foo*)参数将其转换回struct foo或struct Foo Foo=*(
我还想发送一个指向void*函数的指针,这是如何实现的?可以向void*函数发送任何指针吗?不可能;你必须发送一个指针。但是,
void*
可以指向任何东西。如果您的结构变量被调用为foo
,您只需将其作为(void*)&foo
传递,并且在函数内部,您可以使用struct foo*fooPtr=(struct foo*)参数将其转换回struct foo
代码>或struct Foo Foo=*((struct Foo*)参数)代码>
编辑:正如注释中提到的@forsvarir,foo
不能是局部变量(除非调用函数等待线程完成)。请参阅@Gavin Lock的帖子。如前所述,您必须传递一个指针。将void*视为非类型指针,因此必须将其转换回线程函数中的正确类型。(见Aasmund的回答)
正如forsvarir提到的,您必须确保指向的结构在线程使用它之前没有被破坏——最安全的方法是在堆上新建结构,并将其地址和所有权传递给线程函数
我所说的“传递所有权”的意思是,通知结构的函数不能删除它,线程函数必须在处理完结构后删除它。根据您的评论,您需要这样做
在主代码中:
void PassSomeStuff(struct TheStruct myStruct) {
struct TheStruct *pStruct = malloc(sizeof(struct TheStruct));
memcpy(pStruct, &myStruct, sizeof(struct TheStruct));
/* Start the watchdog thread passing in the structure */
pthread_create(/* other args */, &myWatchDogThreadFunc, pStruct); */
}
在监视线程中:
void *myWatchDogThreadFunc(void *pArgs) {
struct TheStruct *pStruct = (struct TheStruct *)pArgs;
/* use the struct */
/* Pass Ownership to the navigation thread*/
/* Start the navigation thread passing in the structure */
pthread_create(/* other args */, &myNavigationThreadFunc, pStruct);
}
在导航线程中:
void *myNavigationThreadFunc(void *pArgs) {
struct TheStruct *pStruct = (struct TheStruct *)pArgs;
/* use the struct */
/* cleanup */
free(pStruct); /* or pass it to somebody else... */
}
你不能只做:
void PassSomeStuff(struct TheStruct myStruct) {
pthread_create(/* other args */, &myStruct);
}
因为myStruct
将被清除。。。当passsomething
返回时。获取地址(获取指向地址的指针)不会复制对象
注:
- 您的任何线程都可以通过调用free来清理该结构,只要您确定所有线程都已完成
- 所有线程(main、watchdog、navigation)都引用同一个结构实例(因此,如果它们正在更改其内容,您可能需要使用锁定来保护它)。如果这不是期望的效果,那么您需要在每个步骤创建(malloc)结构的新副本,以便每个线程都有自己的值副本
这不是一个完整的答案,而是一个替代解决方案,可以替代其他人提出的警告,即在新线程获得该结构时确保该结构仍然存在。当然,您可以使用malloc
获取它,并让新线程负责free
ing它。在许多方面,这似乎是最简单、最便宜的方法(不需要同步),但同步实际上隐藏在malloc
和free
中,并且可能会稍微昂贵,特别是因为大多数面向线程的分配器(例如ptmalloc和tcmalloc)当释放内存的线程与分配内存的线程不同时,会产生额外的成本
您可以使用的另一种方法是在init结构中放置pthread屏障,然后等待它:
pthread_barrier_init(&init_struct.barrier, 0, 2);
pthread_create(&td, 0, start_func, &init_struct);
pthread_barrier_wait(&init_struct.barrier);
并且让线程启动函数也调用pthread\u barrier\u wait(arg->barrier)代码>将结构复制到它自己的自动存储器后。要传递结构,需要传递它的地址(将其转换为指针)。但是,您需要确保对象不会被破坏(因为线程将有一个对它的引用)。是的,您可以传递任何指向空的指针*您不能(AFAIK)。指向基于堆的结构的指针有什么问题吗?我能不能像这样将结构发送到(void*)@Helium3:Yes,但确保结构不会消失。因此,如果它是一个局部变量,例如,函数可能在一个线程中返回,而新线程仍然有一个指向不再存在的对象的指针…@forsvarir:如果我有一个指向GPSLocation的结构。我有一个看门狗线程启动和监控一个GPS I/O线程和一个GPS导航线程。我需要将结构传递给看门狗,然后将它从看门狗传递给导航线程。当它从一个void*中转换回来时,每个线程函数都会复制它吗?如果传入指针,这是否会消除坏数据或结构丢失的可能性/I将从一开始传递指针。在将其发送到看门狗(也是一个线程)之前对其进行malloc,然后看门狗必须将其传递给gps导航线程。那么,我可以沿着void*pthread args传递指针吗?@Helium3:我已经更新了我的帖子,以反映我认为你在说什么,包括底部的一些注释。简短的回答是肯定的(假设我正确地理解了你)。