繁体   English   中英

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

[英]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;
}

在这里,你明确地将keykey2设置为每个线程中的相同值 ,因此在每个线程中它具有相同的值应该不足为奇。 尝试在每个线程中将其设置为不同的值,然后在每个线程中将具有不同的值。

一个常见的模式是:

  1. 调用pthread_getspecific 如果它返回非NULL,请使用该指针。

  2. 如果它返回NULL,则使用动态分配特定于线程的对象的新实例。 调用pthread_setspecific以确保从该线程下一次调用pthread_getspecific返回同一个对象。

  3. 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM