简体   繁体   English

如何正确使用特定于线程的数据

[英]How to use Thread-specific data correctly

I am programming using pthread. 我正在使用pthread进行编程。 I need a global variable that it has different value for different threads. 我需要一个全局变量,它对不同的线程有不同的值。 And threads will use same function to deal with this variable, such as change its value. 并且线程将使用相同的函数来处理此变量,例如更改其值。 If one thread change its value, the value in other threads would not be changed. 如果一个线程更改其值,则不会更改其他线程中的值。 So I tried to use thread specific data, and wrote a example. 所以我尝试使用特定于线程的数据,并写了一个例子。 I need wrap the pthread operations in functions. 我需要在函数中包装pthread操作。 For exapmle: setspecific(), changedata, printdata(), create_key(), delete_key(), etc. 对于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;
}

I create two threads. 我创建了两个线程。 When I make one thread sleep 2 seconds. 当我让一个线程睡2秒。 I get correct answer. 我得到了正确的答案。

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

when I comment /* sleep(2); 当我发表评论/ * sleep(2); */ , I get uncorrect answer. * /,我得到了不正确的答案。

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

I want get the right result without sleep a thread. 我希望在没有睡觉的情况下获得正确的结果。 One thread should not wait for the other thread to finish to call pthread_setspecific() , right? 一个线程不应该等待另一个线程完成调用pthread_setspecific(),对吗? What should I do? 我该怎么办? Thanks for your consideration.Did I right to define struct_data as global variable? 谢谢你的考虑。我有权将struct_data定义为全局变量吗? Anyone can help me? 有人可以帮帮我吗?

int setspecificvar () { /* Set specific data for threads */

    pthread_setspecific (key, &struct_data);
    pthread_setspecific (key2, &temp);

    return 0;
}

Here you explicitly set both key and key2 to the same value in each thread so it shouldn't be surprising that it has the same value in each thread. 在这里,你明确地将keykey2设置为每个线程中的相同值 ,因此在每个线程中它具有相同的值应该不足为奇。 Try setting it to a different value in each thread and then it will have different values in each thread. 尝试在每个线程中将其设置为不同的值,然后在每个线程中将具有不同的值。

A common pattern is this: 一个常见的模式是:

  1. Call pthread_getspecific . 调用pthread_getspecific If it returns non-NULL, use that pointer. 如果它返回非NULL,请使用该指针。

  2. If it returns NULL, use dynamically allocate a new instance of the thread-specific object. 如果它返回NULL,则使用动态分配特定于线程的对象的新实例。 Call pthread_setspecific to ensure the next call to pthread_getspecific from this thread returns that same object. 调用pthread_setspecific以确保从该线程下一次调用pthread_getspecific返回同一个对象。

  3. In the pthread_key_create call, be sure to register a destructor that frees the instance of the thread-specific object when a thread goes away. pthread_key_create调用中,请务必注册析构函数,以便在线程消失时释放特定于线程的对象的实例。

This will give each thread its own instance of a structure. 这将为每个线程提供自己的结构实例。

For example: 例如:

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;
}

This actually sets a different value in each thread. 这实际上在每个线程中设置了不同的值。 And this: 和这个:

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;
}

This actually uses the thread-specific data. 这实际上使用特定于线程的数据。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么要使用线程专用数据? - Why should I use thread-specific data? 特定于线程的数据 - 为什么我不能只使用带有线程ID的静态映射? - Thread-specific data - why can't I just use a static map with thread IDs? 使函数线程安全:线程特定数据与互斥锁 - Making a function thread safe: Thread-specific data vs mutex “将proj4与OpenMP一起使用来进行Segfault”或“如何在OpenMP中使用特定于线程的全局变量” - “Segfault using proj4 with OpenMP” or “How to use thread-specific globals with OpenMP” 在 64 位 OSX 上如何或在哪里设置线程特定的数据预定义结构? - How or where is the thread-specific data predefined structure set on 64 bit OSX? 特定于线程的单例实例 - Thread-specific singleton instances 如何使用 POSIX 线程在 C 中创建特定于线程的全局变量? - How do I create a global variable that is thread-specific in C using POSIX threads? 使用并行算法时的线程特定变量 - Thread-specific variables when using parallel algorithms 在 Python 中记录到线程特定的和共享的日志文件 - Logging to both thread-specific and shared log files in Python 需要线程专用资源时的并行函数 - Parallel functions when I need thread-specific resource
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM