[英]How to use Thread-specific data correctly
我正在使用pthread進行編程。 我需要一個全局變量,它對不同的線程有不同的值。 並且線程將使用相同的函數來處理此變量,例如更改其值。 如果一個線程更改其值,則不會更改其他線程中的值。 所以我嘗試使用特定於線程的數據,並寫了一個例子。 我需要在函數中包裝pthread操作。 對於exapmle:setspecific(),changedata,printdata(),create_key(),delete_key()等。
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
pthread_key_t key;
pthread_key_t key2;
struct test_struct {
int i;
float k;
}struct_data;
int temp;
int setspecificvar () { /* Set specific data for threads */
pthread_setspecific (key, &struct_data);
pthread_setspecific (key2, &temp);
return 0;
}
int changedata (int i, float k, int tempvar) { /* Change specific data for threads */
temp = tempvar;
struct_data.i = i;
struct_data.k = k;
return 0;
}
int printdata (int t) { /* print specific data for threads */
printf ("The addres in child%d returned from pthread_getspecific(key):0x%p\n", \
t, (struct test_struct *)pthread_getspecific(key));
printf ("The value of members in structure bound to \"key\" in child%d:\nstruct_data.i:%d\nstruct_data.k: %f\n", \
t, ((struct test_struct *)pthread_getspecific (key))->i, \
((struct test_struct *)pthread_getspecific(key))->k);
printf ("------------------------------------------------------\n");
printf ("The addres in child%d returned from pthread_getspecific(key2):0x%p\n", \
t, (int *)pthread_getspecific(key2));
printf ("The value of \"temp\" bound to \"key2\" in child%d:%d\n", \
t, *((int *)pthread_getspecific(key2)));
return 0;
}
void *child1 (void *arg)
{
setspecificvar ();
changedata(10, 3.141500, 110); /* Should not change the data in child2 */
printdata(1);
}
void *child2 (void *arg)
{
/* sleep (2); */
setspecificvar ();
changedata(12, 2.141500, 120); /* Should not change the data in child1 */
printdata(2);
changedata (122, 22.141500, 1220); /* Should not change the data in child1 */
printdata (2);
}
int create_key () {
pthread_key_create (&key, NULL);
pthread_key_create (&key2, NULL);
return 0;
}
int delete_key () {
pthread_key_delete (key);
pthread_key_delete (key2);
return 0;
}
int main (void)
{
pthread_t tid1, tid2;
create_key ();
pthread_create (&tid1, NULL, (void *)child1, NULL);
pthread_create (&tid2, NULL, (void *)child2, NULL);
pthread_join (tid1, NULL);
pthread_join (tid2, NULL);
delete_key ();
return 0;
}
我創建了兩個線程。 當我讓一個線程睡2秒。 我得到了正確的答案。
The addres in child1 returned from pthread_getspecific(key):0x0x8049c98
The value of members in structure bound to *"key" in child1*:
*struct_data.i:10
struct_data.k: 3.141500*
------------------------------------------------------
The addres in child1 returned from pthread_getspecific(key2):0x0x8049ca0
The value of "temp" bound to *"key2" in child1*:110
The addres in child2 returned from pthread_getspecific(key):0x0x8049c98
The value of members in structure bound to "key" in child2:
struct_data.i:12
struct_data.k: 2.141500
------------------------------------------------------
The addres in child2 returned from pthread_getspecific(key2):0x0x8049ca0
The value of "temp" bound to "key2" in child2:120
The addres in child2 returned from pthread_getspecific(key):0x0x8049c98
The value of members in structure bound to "key" in child2:
struct_data.i:122
struct_data.k: 22.141500
------------------------------------------------------
The addres in child2 returned from pthread_getspecific(key2):0x0x8049ca0
The value of "temp" bound to "key2" in child2:1220
當我發表評論/ * sleep(2); * /,我得到了不正確的答案。
The addres in child1 returned from pthread_getspecific(key):0x0x8049c54
The addres in child2 returned from pthread_getspecific(key):0x0x8049c54
The value of members in structure bound to "key" in child2:
*struct_data.i:12
struct_data.k: 2.141500*
The value of members in structure bound to *"key" in child1*:
struct_data.i:12
struct_data.k: 2.141500
------------------------------------------------------
The addres in child1 returned from pthread_getspecific(key2):0x0x8049c5c
The value of "temp" bound to *"key2" in child1*:120
------------------------------------------------------
The addres in child2 returned from pthread_getspecific(key2):0x0x8049c5c
The value of "temp" bound to "key2" in child2:120
The addres in child2 returned from pthread_getspecific(key):0x0x8049c54
The value of members in structure bound to "key" in child2:
struct_data.i:122
struct_data.k: 22.141500
------------------------------------------------------
The addres in child2 returned from pthread_getspecific(key2):0x0x8049c5c
The value of "temp" bound to "key2" in child2:1220
我希望在沒有睡覺的情況下獲得正確的結果。 一個線程不應該等待另一個線程完成調用pthread_setspecific(),對嗎? 我該怎么辦? 謝謝你的考慮。我有權將struct_data定義為全局變量嗎? 有人可以幫幫我嗎?
int setspecificvar () { /* Set specific data for threads */
pthread_setspecific (key, &struct_data);
pthread_setspecific (key2, &temp);
return 0;
}
在這里,你明確地將key
和key2
設置為每個線程中的相同值 ,因此在每個線程中它具有相同的值應該不足為奇。 嘗試在每個線程中將其設置為不同的值,然后在每個線程中將具有不同的值。
一個常見的模式是:
調用pthread_getspecific
。 如果它返回非NULL,請使用該指針。
如果它返回NULL,則使用動態分配特定於線程的對象的新實例。 調用pthread_setspecific
以確保從該線程下一次調用pthread_getspecific
返回同一個對象。
在pthread_key_create
調用中,請務必注冊析構函數,以便在線程消失時釋放特定於線程的對象的實例。
這將為每個線程提供自己的結構實例。
例如:
int setspecificvar () { /* Set specific data for threads */
struct test_struct *s = malloc(sizeof(struct test_struct));
int *i = malloc(sizeof(int *));
memset(s, 0, sizeof(s));
memset(i, 0, sizeof(i));
pthread_setspecific (key, s);
pthread_setspecific (key2, i);
return 0;
}
這實際上在每個線程中設置了不同的值。 和這個:
int changedata (int i, float k, int tempvar) { /* Change specific data for threads */
struct test_struct *struct_data = pthread_getspecific(key);
int *temp = pthread_getspecific(key2);
*temp = tempvar;
struct_data->i = i;
struct_data->k = k;
return 0;
}
這實際上使用特定於線程的數據。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.