2015-10-16 68 views
1

我刚刚开始研究pthread的跨平台。但我对用于pthread_create()pthread_join()的变量类型非常困惑。请看下面的代码。关于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; 
} 

正如我在评论中写的,我不明白这些指针,它对我来说没有意义。

对于第一个,为什么我必须为指针类型放置值类型1?

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

+0

请一次提出一个问题。 –

+0

但是我认为这是最后一个问题,这个问题是关于C++中的POINTER的。不是关于实际功能。 – Jenix

+1

你想跨平台的代码?使用C++的'std :: thread'! –

回答

1

您的函数myThreadFunc将一个指针指向内存中的任何位置。我们不知道该位置的类型,所以它是一个void *,并将其转换为您想要的任何类型。您将其转换为指向整数argForThread的指针,该指针将为&argForThread,然后对其进行反驳,从而产生值10.

您的返回语句不正确。您正在返回&result,但变量在堆栈中。一旦函数返回,变量不再存在。如果你想要返回一个计算值给调用者,你需要为它分配内存,然后返回分配内存的地址。调用者然后会去除它接收到的地址,获取值,最后释放内存。 (新手程序员可能会返回静态值的地址或堆栈中的某个地址,但这不会是线程安全的。)

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

线程结果是void **,因为你传入的指针会被突变指向由myThreadFunc返回的位置。因此,在您的示例中,threadResult将以值result * result结尾,因此它将指向无效的内存位置。在你的例子中没关系,因为threadResult是一个整数,而不是指针。

+0

感谢您的亲切解释,并指出我在退货声明中的错误,现在我编辑了。但仍然不明白为什么我不能把'(void *)&result'和'(void *)result'放在一起。 'void *'是指针类型,'result'本身就是一个值。 – Jenix

+1

'result'是函数返回时不再存在的堆栈变量。如果你返回'&result',你将返回一个指向内存中的位置的指针,这个位置可能很快就会变得非常不同。 – vy32

+0

您希望返回结果的*值*,而不是无意义的地址在即将不复存在的堆栈上。 –