C 试图理解指针和线程
我对C语言相当陌生,并且试图理解线程和指针。据我所知,这条线创建了一个线程C 试图理解指针和线程,c,multithreading,pointers,C,Multithreading,Pointers,我对C语言相当陌生,并且试图理解线程和指针。据我所知,这条线创建了一个线程 rc = pthread_create(&threads[t], NULL, PrintHello, (void *)t); 第四个参数是指针函数(void*)t的参数,这是一个指向变量t地址的指针,该变量是long类型?指针函数将void指针的参数带到变量,即(void*)t #include <pthread.h> #include <stdio.h> #include <s
rc = pthread_create(&threads[t], NULL, PrintHello, (void *)t);
第四个参数是指针函数(void*)t
的参数,这是一个指向变量t
地址的指针,该变量是long
类型?指针函数将void指针的参数带到变量,即(void*)t
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#define NUM_THREADS 20
void *PrintHello(void *threadid)
{
long tid;
tid = (long)threadid;
printf("Hello World! It's me, thread #%ld!\n", tid);
pthread_exit(NULL);
}
int main(int argc, char *argv[])
{
pthread_t threads[NUM_THREADS];
int rc;
long t;
for(t=0;t<NUM_THREADS;t++){
printf("In main: creating thread %ld\n", t);
rc = pthread_create(&threads[t], NULL, PrintHello, (void *)t);
if (rc){
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
}
/* Last thing that main() should do */
pthread_exit(NULL);
}
所以现在void指针仍然指向变量t
而*(long*)threadid
正在反引用变量t
?
并在所有线程中输出t
的最终值
我不确定我是否理解正确,如果我误解了什么地方,我很感激任何建议。我的问题是关于
(void*)t
和(void*)&t
,它们都是指向变量t
地址的指针,我读到的指针只能指向地址,不能指向值,那么为什么(void*)t
会输出t
的递增值呢<代码>任务ID=*(长*)线程ID如果我只做taskid=threadid
它会打印出t
的地址,*(long*)
做什么?括号外的*
正在取消引用?要获取变量的地址,必须使用&
(void*)t
未获取t
的地址。它接受t
的值,并将该值视为void*
值。所以你有一个指向内存地址0,1,2。。。最多可使用NUM_线程-1
不能使用这些指针,因为它们不指向有效地址。但您可以使用(long)threadid
再次将它们视为数字
需要将类型设为void*的唯一原因是pthreads将其用作thread函数的参数。如果使用了
void*PrintHello(long-threadid)
,则调用pthread\u create
时会出现错误,这表示函数的类型错误。在将某个值转换为该数据类型之前,先将类型放在括号中。因此,在您的示例中,(void*)t
将t
的值从long
转换为void*
。之所以这样做,是因为pthread\u create
需要一个指针
将&
放在某物前面可以得到它的地址。因此&t
获取t
的地址。然后,它将被强制转换为如上所述的void*
,尽管实际上并不需要它,因为如果需要,任何指针都将自动转换为void*
因此,在代码的第一个版本中,您将t
的实际值传递到线程中,方法是将其强制转换为指针,然后再次将其强制转换回线程中,以获得long
值
第二个版本在中传递一个指向t
的指针,因此每个线程将在到达此行时打印出t
的值:
taskid = *(long *)threadid;
taskid=*(长*)线程ID;在这一行中,我将它转换回long,但由于它是指向t的指针,我必须使用括号外的*来获取值,并且转换(long*),因为它是指针?否则,如果我只是强制转换(long)就不起作用了,因为t是指针?不完全是。您要将其强制转换为
long*
,然后取消对它的引用。你不能取消引用void*
指针。明白了,非常感谢你的解释,我现在更明白了:)所以在第二个例子中,我必须强制转换(长*)threadid,因为我要传递指向t的指针,换句话说,t的地址?@aalang是的。我希望您也能理解为什么它会在所有线程中打印最终值。我有点明白为什么,但这是因为我调用了sleep(1),当它完成sleep时,t值已经是最终值了,所以它只开始将taskid分配给threadid?是的,这就是原因。(我不确定“它只开始将taskid分配给threadid”是什么意思,但您所说的其余内容是正确的)我的意思是,在它睡眠后,只执行taskid=threadid中的其余代码,而此时它已经是最终值了
taskid = *(long *)threadid;