您好我很难理解如何从c中的一个线程返回一个值。我有这个工作的例子:
#define NTHREADS 4
void *neg (void * param) {
int *l;
l=(int *) param;
int *r=(int *)malloc(sizeof(int));
*r=-*l;
return ((void *) r);
}
int main (int argc, char *argv[]) {
pthread_t threads[NTHREADS];
int arg[NTHREADS];
int err;
for(long i=0;i<NTHREADS;i++) {
arg[i]=i;
err=pthread_create(&(threads[i]),NULL,&neg,(void *) &(arg[i]));
if(err!=0)
error(err,"pthread_create");
}
for(int i=0;i<NTHREADS;i++) {
int *r;
err=pthread_join(threads[i],(void **)&r);
printf("Resultat[%d]=%d\n",i,*r);
free(r);
if(err!=0)
error(err,"pthread_join");
}
return(EXIT_SUCCESS);
}
我觉得很难理解如下:
函数neg返回一个指向(void *)的指针* r,指向堆中的值。因此基本上将地址返回到堆中。然后在pthread_join中我们通过做&amp; r得到那个返回值(这本身看起来不合逻辑?抓住地址的地址?)然后转换为指针的指针?为什么我们这样做?
感谢您的帮助!
答案 0 :(得分:2)
考虑这段代码,该代码完全有效并打印&#34; 5 5 5 5&#34;。
int x = 5;
int *p = &x;
int **pp = &p;
int ***ppp = &pp;
printf("%d %d %d %d\n", x, *p, **pp, ***ppp);
return 0;
C允许您拥有任何深度的指针,使用相应数量的地址运算符进行初始化。在您的示例中,您分配了int *
并且该函数必须返回void **
,因此您必须取消引用结果两次并将其强制转换,这是通过转换int *
完成的。
那么,&#34;抓住地址的地址?&#34; Yup!嗯,指针的地址,它可能包含int的地址或另一个指针。
答案 1 :(得分:0)
然后在pthread_join中我们通过做&amp; r得到那个返回值 本身似乎不合逻辑?抓住地址的地址?)然后施展到 指针的指针?为什么我们这样做?
首先需要了解的是线程函数不会直接返回值;他们使用pthread_exit()
将值发送到pthreads库或返回一个值(如您的示例中所示)和
通过调用pthread_join()
(通过使用线程标识符)检索它。由于返回值是指针,因此必须
传递一个指向指针的指针,以便从pthread_join()
函数中检索它。
出于理解目的,请考虑以下伪代码:
/* thread */
void *neg(void *arg)
{
return ptr; // let's say "ptr" is stored in the library as "retval_thread_id"
}
int pthread_joing(pthread_t thread_id, void **retval)
{
*retval = retval_thread_id;
}
int main(void)
{
rc = pthread_join(threads[i],(void **)&r);
}
那么,如何在不使用指针指针的情况下从retval_thread_id
检索指针pthread_join()
?
这与将ptr-to-ptr传递给函数没有什么不同,函数存储在传递指针的指针对象中:
void func(int **p)
{
*p = malloc(10 * sizeof *p);
}
int main(void)
{
int *p;
func(&p);
}
顺便说一句,你做的所有演员表(除了pthread_join()
的电话中的那个演员 - 如果你将r
声明为void *r;
,你也不会这样做。)不必要。可以在没有强制转换的情况下将void指针分配给C中的任何其他数据指针。