title: How to use Thread-specific data correctly
body: <p>I am programming using 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. For exapmle: setspecific(), changedata, printdata(), create_key(), delete_key(), etc.</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;pthread.h&gt;
  
  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, &amp;struct_data);
      pthread_setspecific (key2, &amp;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))-&gt;i,                            \
              ((struct test_struct *)pthread_getspecific(key))-&gt;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 (&amp;key, NULL);
      pthread_key_create (&amp;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 (&amp;tid1, NULL, (void *)child1, NULL);
      pthread_create (&amp;tid2, NULL, (void *)child2, NULL);
      pthread_join (tid1, NULL);
      pthread_join (tid2, NULL);
  
      delete_key ();
  
      return 0;
  }
  </code></pre>
  
  <p>I create two threads. When I make one thread sleep 2 seconds. I get correct answer.</p>
  
  <pre><code>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
  </code></pre>
  
  <p>when I comment /* sleep(2); */ , I get uncorrect answer.</p>
  
  <pre><code>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
  </code></pre>
  
  <p>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? What should I do? Thanks for your consideration.Did I right to define struct_data as global variable? Anyone can help me?</p>