Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 将普通数据传递到pthread void*_C_Pthreads - Fatal编程技术网

C 将普通数据传递到pthread void*

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=*(

pthread函数采用void*参数。如何发送普通结构而不是指针

我想向一个pthread函数发送一个非指针结构


我还想发送一个指向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:我已经更新了我的帖子,以反映我认为你在说什么,包括底部的一些注释。简短的回答是肯定的(假设我正确地理解了你)。