Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 试图理解指针和线程_C_Multithreading_Pointers - Fatal编程技术网

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

我对C语言相当陌生,并且试图理解线程和指针。据我所知,这条线创建了一个线程

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;