Chinaunix首页 | 论坛 | 博客
  • 博客访问: 147650
  • 博文数量: 27
  • 博客积分: 531
  • 博客等级: 一等列兵
  • 技术积分: 332
  • 用 户 组: 普通用户
  • 注册时间: 2012-02-25 18:31
文章分类

全部博文(27)

文章存档

2015年(4)

2014年(3)

2013年(6)

2012年(14)

我的朋友

分类: LINUX

2012-08-11 15:59:17

    线程作为一个重要的编程模型,在服务类程序中大量的使用。并发、同步等概念大家都耳熟能详。
    一个进程中的线程共享同样的资源,在一般情况下不会存在问题,但是当对每个线程要有特殊的属性时,
就会存在问题,例如函数修改一个在堆上分配的buff,此时不同的线程调用该函数时,都会对这个buff进行
修改。这样,数据的一致性就得不到保证。
     线程似有变量给这个问题提供了解决方案。一下是一段C++代码,使用基于linux系统,使用线程私有数据
模型。

点击(此处)折叠或打开

  1. /*************************************************************
  2.  * 用于学习使用线程似有数据的使用,同样的一个key,对不同的线程
  3.  * 关联到不同的数据对象,使用相应的 getset 加上 key 操作这
  4.  * 个数据。
  5.  *
  6.  * dinglonglong
  7.  * 2012-08-11
  8.  * **********************************************************/
  9. #include <pthread.h>
  10. #include <unistd.h>
  11. #include <cstring>
  12. #include <cstdio>
  13. #include <cstdlib>

  14. pthread_key_t key;
  15. pthread_once_t init_done = PTHREAD_ONCE_INIT;

  16. /**
  17.  * 初始化key
  18.  */
  19. void thread_init()
  20. {
  21.     pthread_key_create(&key, free);
  22. }

  23. /**
  24.  * 向现成的buff中写数据
  25.  */
  26. char* init_buff(char* prex, int index)
  27. {
  28.     char* buff = (char*)pthread_getspecific(key);
  29.     if (buff == NULL) {
  30.         buff = (char*)malloc(strlen(prex) + 2);
  31.         pthread_setspecific(key, buff);
  32.     }

  33.     sprintf(buff, "%s:%d", prex, index);
  34.     return buff;
  35. }

  36. /**
  37.  * 线程函数
  38.  */
  39. void* tf(void* arg)
  40. {
  41.     pthread_once(&init_done, thread_init);

  42.     for (int i = 0; i < 10; i++) {
  43.         char* res = init_buff((char*)arg, i);
  44.         printf("%s\n", res);

  45.         sleep(1);
  46.     }

  47.     return NULL;
  48. }

  49. /**
  50.  * test
  51.  */
  52. int main(int argc, char* argv[])
  53. {
  54.     void* ret;
  55.     char* name_1 = (char*)"thread_1";
  56.     char* name_2 = (char*)"thread_2";
  57.     pthread_t pt_1;
  58.     pthread_t pt_2;

  59.     pthread_create(&pt_1, NULL, tf, name_1);
  60.     pthread_create(&pt_2, NULL, tf, name_2);

  61.     pthread_join(pt_1, &ret);
  62.     pthread_join(pt_2, &ret);

  63.     printf("main over.\n");

  64.     return 0;
  65. }

// 编译:g++ -lpthread test.cpp -o test

// 运行结果:

thread_2:0
thread_1:0
thread_2:1
thread_1:1
thread_2:2
thread_1:2
thread_2:3
thread_1:3
thread_2:4
thread_1:4
thread_1:5
thread_2:5
thread_2:6
thread_1:6
thread_2:7
thread_1:7
thread_1:8
thread_2:8
thread_2:9
thread_1:9
main over.


    使用init_thread函数创建key,在每个线程中,用这个key去取buff,如果没有则malloc一个,pthread_once
保证这个key只被创建一次,避免初始化时的竞争。
    从打印可以看出,每个线程使用自己的buff,彼此之间没有冲突。

同样对java来说,也存在线程私有变量的说法,java代码如下:

点击(此处)折叠或打开

  1. public class TestThreadLoacl extends Thread {
  2.     public static ThreadLocal<String> threadLocal = new ThreadLocal<String>();

  3.     private String name;

  4.     public TestThreadLoacl(String name) {
  5.         this.name = name;
  6.     }

  7.     public void run() {
  8.         for (int i = 0; i < 10; i++) {
  9.             System.out.println(threadLocal.get());
  10.             threadLocal.set(name + " set value: " + i);

  11.             try {
  12.                 Thread.sleep(1000);
  13.             } catch (InterruptedException e) {
  14.                 e.printStackTrace();
  15.             }
  16.         }
  17.     }

  18.     /**
  19.      * main test
  20.      */
  21.     public static void main(String[] args) {
  22.         threadLocal.set("main set value: main.");
  23.         
  24.         (new TestThreadLoacl("Thread_1")).start();
  25.         (new TestThreadLoacl("Thread_2")).start();
  26.     }
  27. }

// 运行结果:

null
null
Thread_1 set value: 0
Thread_2 set value: 0
Thread_1 set value: 1
Thread_2 set value: 1
Thread_1 set value: 2
Thread_2 set value: 2
Thread_1 set value: 3
Thread_2 set value: 3
Thread_1 set value: 4
Thread_2 set value: 4
Thread_1 set value: 5
Thread_2 set value: 5
Thread_1 set value: 6
Thread_2 set value: 6
Thread_1 set value: 7
Thread_2 set value: 7
Thread_1 set value: 8
Thread_2 set value: 8



阅读(2588) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~