pthread函數採用void *參數。一個普通的結構,而不是一個指針如何發送?將普通數據傳遞給pthread void *
我想發送一個非指針結構到一個pthread函數。
另外我想發送一個指向void *函數的指針,這是如何完成的?可以將任何指針發送給void *函數嗎?
pthread函數採用void *參數。一個普通的結構,而不是一個指針如何發送?將普通數據傳遞給pthread void *
我想發送一個非指針結構到一個pthread函數。
另外我想發送一個指向void *函數的指針,這是如何完成的?可以將任何指針發送給void *函數嗎?
不可能;你必須發送一個指針。然而,void *
可以指向任何東西。如果你的struct變量被調用foo
,你可以簡單地將它作爲(void *) &foo
傳遞,並且在函數內部,你可以將它轉換回例如struct Foo
與struct Foo * fooPtr = (struct Foo *) param;
或struct Foo foo = *((struct Foo *) param);
。
編輯:作爲@forsvarir在評論中提到,foo
一定不是是一個局部變量(除非調用函數等待線程完成)。請參閱@Gavin Lock的文章。
如前所述,您必須傳遞一個指針。把void *想象成一個無類型的指針,所以你必須把它轉換回你的線程函數中正確的類型。 (請參閱Aasmund的答案)
正如forsvarir提到的,您必須確保指向的結構在線程使用之前不被銷燬 - 最安全的方法是在堆上新建結構並傳遞其地址並擁有線程功能。
我的意思是「傳遞所有權」那是什麼的函數,消息結構不得刪除它,線程函數必須刪除結構一旦用它做。
+1有關所有權的觀點。 – 2011-05-04 10:14:21
根據您的意見,你需要做這樣的事情......
在主代碼:
void PassSomeStuff(struct TheStruct myStruct) {
struct TheStruct *pStruct = malloc(sizeof(struct TheStruct));
memcpy(pStruct, &myStruct, sizeof(struct TheStruct));
/* Start the watchdog thread passing in the structure */
pthread_create(/* other args */, &myWatchDogThreadFunc, pStruct); */
}
在你的看門狗線程:
void *myWatchDogThreadFunc(void *pArgs) {
struct TheStruct *pStruct = (struct TheStruct *)pArgs;
/* use the struct */
/* Pass Ownership to the navigation thread*/
/* Start the navigation thread passing in the structure */
pthread_create(/* other args */, &myNavigationThreadFunc, pStruct);
}
在您的導航線:
void *myNavigationThreadFunc(void *pArgs) {
struct TheStruct *pStruct = (struct TheStruct *)pArgs;
/* use the struct */
/* cleanup */
free(pStruct); /* or pass it to somebody else... */
}
你不能只是做:
void PassSomeStuff(struct TheStruct myStruct) {
pthread_create(/* other args */, &myStruct);
}
因爲myStruct
將得到清理...當PassSomeStuff
回報。獲取地址(獲取指針)不會複製對象。
注:
這不是一個完整的答案,而是另一種解決方案,以警告其他人提供的有關確保新線程獲得結構時仍然存在的警告。當然你可以用malloc
來獲得它,並給新線程負責free
。在許多方面,這似乎是最簡單和最便宜的方式(不需要同步),但同步實際上隱藏在malloc
和free
之內,並且可能會稍微昂貴,尤其是因爲大多數面向線程的分配器(例如ptmalloc和tcmalloc)會產生額外的當釋放內存的線程與分配內存的線程不一樣時的成本。
,你可以使用不同的方法是把一個並行線程屏障在你的初始化結構內,並在其上等待:
pthread_barrier_init(&init_struct.barrier, 0, 2);
pthread_create(&td, 0, start_func, &init_struct);
pthread_barrier_wait(&init_struct.barrier);
而且具有線程啓動功能也呼籲pthread_barrier_wait(arg->barrier);
的結構複製到它自己的自動後存儲。
要傳遞一個結構體,你需要傳遞它的地址(將它轉換爲一個指針)。但是,您需要確保該對象不會被破壞(因爲該線程將引用該對象)。 是的,你可以將任何指針傳遞給void * – forsvarir 2011-05-04 10:01:54
你不能(AFAIK)。指向基於堆的struct的指針有什麼問題? – 2011-05-04 10:02:12
我可以不只是像這樣的&thestruct發送結構到(void *) – jarryd 2011-05-04 10:04:32