[英]Trying to understand pointers and threads
我對 C 相當陌生,並試圖理解線程和指針。 據我所知,這條線創建了一個線程
rc = pthread_create(&threads[t], NULL, PrintHello, (void *)t);
第四個參數是指針函數(void *)t
,這是一個指向long
類型變量t
的地址的指針? 指針函數將 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);
}
之后,我將指針函數和pthread_create
更改為:
{
long taskid;
sleep(1);
taskid = *(long *)threadid;
printf("Hello from thread %ld\n", taskid);
pthread_exit(NULL);
}
rc = pthread_create(&threads[t], NULL, PrintHello, (void *) &t);
所以現在 void 指針仍然指向變量t
的地址?
並且*(long *)threadid
正在取消引用變量t
? 它在所有線程中輸出t
的最終值。
我不確定我是否理解正確,如果我誤解了某處,我很感激任何建議。 我的問題是(void *)t
和(void *) &t
,它們都是指向變量t
的地址的指針,我讀取的指針只能指向地址而不是值,那么為什么(void *)t
輸出的遞增值t
? taskid = *(long *)threadid;
如果我只執行taskid = threadid
它會打印出t
的地址, *(long *)
什么作用? 括號外的*
是取消引用?
要獲取變量的地址,您必須使用&
。
(void*)t
沒有得到t
的地址。 它采用t
的值,並將該值視為void*
值。 所以你有一個指向內存地址 0, 1, 2, ... 直到 NUM_THREADS-1 的指針。
您不能使用這些指針,因為它們不指向有效地址。 但是您可以使用(long)threadid
再次將它們視為數字。
您需要使類型void*
的唯一原因是因為 pthreads 將其用作線程函數的參數。 如果您使用了void *PrintHello(long threadid)
那么在調用pthread_create
時會出現錯誤,表示該函數的類型錯誤。
在將該值轉換為該數據類型之前將類型放在括號中。 因此,在你的例子(void *) t
轉換的價值t
從long
到一個void *
。 這樣做是因為pthread_create
需要一個指針。
將&
放在某物前面會得到它的地址。 所以&t
得到的地址t
。 然后它被轉換為void *
如上所述,盡管它不是真正需要的,因為如果需要,任何指針都會自動轉換為void *
。
因此,在您的代碼的第一個版本中,您將t
的實際值傳遞到您的線程中,方法是將其強制轉換為使其看起來像一個指針,然后在線程內再次將其強制轉換以獲取long
值。
第二個版本是傳遞一個指向t
in 的指針,因此每個線程將在到達這一行時打印出t
的值:
taskid = *(long *)threadid;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.