c - 取消引用 void * 就像 (int) -- 标准做法?

标签 c multithreading void

我试图打印线程的返回值,发现我仍然对双空指针的概念感到困惑。

我的理解是, void* 是指向任何数据类型的指针,可以通过适当的强制转换取消引用,但否则引用的“级别”会像常规类型指针一样被保留(即,您不能期望得到与您放入 **(int **)depth2 的值相同,只需取消引用一次即可,如 *depth2。)。

但是,在我为线程返回打印而整理的代码(下面)中,似乎我没有取消引用一个空指针当我将其转换到 (int) 时。这是地址被用作值的情况吗?如果是这样,这是从线程返回的正常方式吗?不然我还缺什么??

(我知道在线程内操作数据的更安全方法可能是调用者级存储,但我对这种情况非常感兴趣,以及我不明白 void 指针是什么。)

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

void *myThread(void *arg)
{
    return (void *)42;
}

int main()
{
    pthread_t tid;
    void *res;                                        // res is itself a void *

    pthread_create(&tid, NULL, myThread, NULL);
    pthread_join(tid, &res);                          // i pass its address, so void** now
    printf(" %d \n", (int)res);                       // how come am i able to just use it as plain int?

    return 0;
}

最佳答案

首先,pthread_join()的目的是更新void * 通过第二个参数给出以获得结果 线程函数(void *)。
当您需要更新 int 时,如 scanf("%d", &my_var); 参数 是要更新的 int 的地址:一个 int *
出于同样的原因,您可以通过提供 void ** 来更新 void *

在您的示例的具体情况下,我们不使用返回的 void * 以正常方式:这是一个技巧!
由于指针可以被认为是一个大整数,计算其中的字节数 一个很长的行,技巧是假设这个指针可以简单地存储 不引用任何内存位置的整数值。

在您的示例中,返回 (void *)42 相当于说 “你会在地址 42 发现一些有趣的东西”。
但该地址从未放置过任何东西!
这是一个问题吗?不,只要没有人试图取消引用它 指针以检索地址 42 处的内容。

执行pthread_join()后,变量res 已更新并包含返回的 void *: 在本例中为 42。
我们在这里通过假设记住的信息来执行反向技巧 此指针并不指向内存位置,而是一个简单的整数。

它可以工作,但是这非常丑陋!
主要优点是避免了 malloc()/free() 的昂贵成本

void *myThread(void *arg)
{
  int *result=malloc(sizeof(int));
  *result=42;
  return result;
}

...
int *res;
pthread_join(tid, &res);
int result=*res; // obtain 42
free(res);

避免这种成本的更好解决方案是使用参数 线程函数。

void *myThread(void *arg)
{
  int *result=arg;
  *result=42;
  return NULL;
}

...
int expected_result;
pthread_create(&tid, NULL, myThread, &expected_result);
pthread_join(tid, NULL);
// here expected_result has the value 42

关于c - 取消引用 void * 就像 (int) -- 标准做法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60875880/

相关文章:

c - 下次调用函数后,上次调用的字符串 "remembered"

c - 为什么 C == 对于相等的字符串返回 true?

Java并行多个任务超时

c# - 在递归调用中使用 lock(obj)

c - 返回类型为空。我的职能也需要帮助

c - 警告 : control reaches end of non-void function [-Wreturn-type]

swift - 无法将 'Void'类型的值(也称为 '()')分配给 '() -> Void'类型

c - 带引用参数的 printf

c - 让 asprintf 使用同时也是输入的非 NULL 目标指针是否安全?

java - Android socket.close() 导致 "the system call was canceled"?