c - 关于 pthread_create() 和 pthread_join()

标签 c linux multithreading pointers pthreads

刚开始研究跨平台的pthread。但我真的很困惑用于 pthread_create()pthread_join() 的变量类型。请看下面的代码。

// This is just simple code for test, so don't take this variable seriously!
int result;
void* myThreadFunc(void* arg) {
    result = *(int*)arg;

    // Why not &result, but result???
    return (void*)result;
}

int main() {
    pthread_t myThread;
    int argForThread = 10;
    int threadResult = 0;

    pthread_create(&myThread, NULL, myThreadFunc, (void*)&argForThread);

    // Why (void**), but not (void*)?
    pthread_join(myThread, (void**)&threadResult);

    return 0;
}

正如我在评论中所写,我不理解那些指针,对我来说没有意义。

对于第一个,为什么我必须把值类型放在一个指针类型上?

对于第二个,为什么我只需要对局部变量的地址进行双指针转换?

最佳答案

您的函数 myThreadFunc 将指向内存中任何位置的指针作为其参数。我们不知道该位置的类型,所以它是一个 void * 并且您可以将其转换为您想要的任何类型。您将其转换为指向整数 argForThread 的指针,即 &argForThread,然后取消引用它,生成值 10。

您的返回声明不正确。您正在返回 &result 但变量在堆栈上。一旦函数返回,变量就不再存在。如果要将计算值返回给调用者,则需要为其分配内存,然后返回分配内存的地址。然后,调用者将取消引用它接收到的地址,获取值,最后释放内存。 (新手程序员可能会返回静态值的地址或堆栈上的某些内容,但这不是线程安全的。)

当您返回(void *)result 时,您将返回值result,就像它是指向内存中某处的指针一样。该内存位置几乎肯定是无效的。但是,这并不重要,因为您不会取消引用返回的位置。 (我应该注意到,在具有 32 位整数和 64 位指针的系统上,您会遇到不可预测的行为。)

线程结果是一个void **,因为您传递的是一个指针,该指针将被突变为指向myThreadFunc 返回的位置。因此,在您的示例中,threadResult 将以值 result * result 结束,因此它将指向无效的内存位置。这在您的示例中没问题,因为 threadResult 是一个整数,而不是指针。

关于c - 关于 pthread_create() 和 pthread_join(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33177641/

相关文章:

c++ - 如何以编程方式在 linux 中获取设备/分区的 uuid?

c# - 从多个线程修改 Entity Framework 实体

c - 学习C : noob suitable debugger

c - 如何在 C 中用循环打印特定数字?

java - CentOS 7 上的 Tomcat 8 管理器访问被拒绝(错误 403)而不提示输入登录名/密码

c# - 如何使用线程在控制台上同时进行读/写

java - ThreadPoolExecutor 的 Thread.join()

增加 C 中自动数组的大小后出现编译器错误

C动态复制字符串

linux - 为什么 linux id 命令给我关于同一帐户的不同信息?