Chinaunix首页 | 论坛 | 博客
  • 博客访问: 655047
  • 博文数量: 171
  • 博客积分: 2246
  • 博客等级: 大尉
  • 技术积分: 1574
  • 用 户 组: 普通用户
  • 注册时间: 2012-05-31 11:45
文章分类

全部博文(171)

文章存档

2018年(3)

2017年(4)

2015年(1)

2014年(20)

2013年(57)

2012年(86)

分类: LINUX

2013-10-09 16:39:09

FROM:http://blog.csdn.net/wallwind/article/details/8136134

    因为项目中需要用到主线程类共享所有数据,而主线程又要生成几个线程,而几个线程要用到主线程的数据,因此每个线程要保存一个主线程类指针,类似于自己的私有资源。因此就要用到这个类,主要是因为如果用多线程对同样的资源同步的话,就要对资源进行加锁、线程就要同步,那么同步就会涉及到线程的切换问题,而频繁切换就会导致cpu工作压力增大...,因此,根据情况利用适合的方法很重要......

 

下面开始介绍pthread_key_create的使用

  1. #include <pthread.h>  
  2. int pthread_key_create(pthread_key_t *key, void (*destructor)(void*));   

还有

pthread_getspecific(), pthread_key_delete(),

几个函数

对其进行封装,每次调用设置全局变量就OK

 

下面cpp代码仅供学习
mytls.h

  1. /**
  2.     create by wallwind
  3.     mail:wochenglin@qq.com
  4.     2012/11/1
  5.      
  6. **/
  7.       
  8.     #ifndef _MyTLS_h__
  9.     #define _MyTLS_h__
  10.  
  11.     #include <pthread.h>
  12.     enum {NAME_SIZE =20,THREAD_NUM=10,};
  13.       
  14.     //typedef DWORD pthread_key_t;
  15.     const pthread_key_t INVALID_PTHREAD_KEY = (pthread_key_t)0xFFFFFFFF;
  16.     //typedef void (*destory_callback)(void*);
  17.     //MyTLSPtr必须为进程全局变量,并且在初始化时直接申请key,而不是在第一次set时使用once方式来初始化key
  18.     //暂时不使用线程关闭时自动释放的方式,仍然使用谁创建谁释放的原则
  19.       
  20.     class MyTLSPtr
  21.     {
  22.     public:
  23.             MyTLSPtr():m_key(INVALID_PTHREAD_KEY)
  24.             {
  25.                     init();
  26.             }
  27.             virtual ~MyTLSPtr()
  28.             {
  29.                     destory();
  30.             }
  31.     public:
  32.       
  33.             template< typename T >
  34.             void set(T* pPtr)
  35.             {
  36.                     pthread_setspecific(m_key, pPtr);
  37.             }
  38.       
  39.             template< typename T >
  40.             T* get() const
  41.             {
  42.                     return static_cast<T*>(pthread_getspecific(m_key));
  43.             }
  44.       
  45.             void init()
  46.             {
  47.                     if(m_key != INVALID_PTHREAD_KEY)
  48.                     {
  49.                             destory();
  50.                     }
  51.       
  52.                     pthread_key_create(&m_key, NULL);
  53.             }
  54.       
  55.             void destory()
  56.             {
  57.                     if(m_key == INVALID_PTHREAD_KEY)
  58.                             return;
  59.       
  60.                     pthread_key_delete(m_key);
  61.       
  62.                     m_key = INVALID_PTHREAD_KEY;
  63.             }
  64.       
  65.     private:
  66.             pthread_key_t m_key;
  67.             //destory_callback m_pCallBack;
  68.     };
  69.       
  70.     template< typename T >
  71.     class MyTLSTypePtr : public MyTLSPtr
  72.     {
  73.     public:
  74.             MyTLSTypePtr()
  75.                     :MyTLSPtr()
  76.             {}
  77.             virtual ~MyTLSTypePtr()
  78.             {}
  79.       
  80.     public:
  81.             void set(T* pPtr)
  82.             {
  83.                     MyTLSPtr::set<T>(pPtr);
  84.             }
  85.       
  86.             T* get() const
  87.             {
  88.                     return MyTLSPtr::get<T>();
  89.             }
  90.     };
  91.       
  92.     #endif // MyTLS_h__
  1. //create by wallwind mail:wochenglin@qq.com 2012/11/1

  2.     #include <malloc.h>
  3.     #include <pthread.h>
  4.     #include <stdio.h>
  5.       
  6.     #include "MyTLS.h"
  7.     //enum {NAME_SIZE =20,THREAD_NUM=10,};
  8.       
  9.     MyTLSPtr g_TLS;
  10.       
  11.     void write_to_thread_log (const char* message);
  12.       
  13.     void* thread (void* args)
  14.     {
  15.             char log[NAME_SIZE];
  16.             FILE* file;
  17.             sprintf(log,"thread_%d.log",(int)pthread_self());
  18.       
  19.             file = fopen (log, "w");
  20.             g_TLS.set(file);
  21.       
  22.             write_to_thread_log ("message test");
  23.     }
  24.       
  25.       
  26.     void write_to_thread_log (const char* message)
  27.     {
  28.       
  29.             FILE* thread_log = g_TLS.get<FILE>();
  30.             fprintf (thread_log, "%s\n", message);
  31.       
  32.     }
  33.     int main()
  34.     {
  35.             int i;
  36.             pthread_t threads[THREAD_NUM];
  37.       
  38.             for(i = 0; i<THREAD_NUM;i++) //创建线程
  39.                     pthread_create(&threads[i],NULL,thread,NULL);
  40.       
  41.             for(i = 0;i<THREAD_NUM;i++) //主线程阻塞生成线程
  42.       
  43.                     pthread_join(threads[i],NULL);
  44.             return 0;
  45.     }


  生成的文件为

 同理c代码如下(效果同上cpp文件):


  1. #include <stdio.h>
  2. #include <pthread.h>
  3. #include <malloc.h> 

  4. static pthread_key_t thread_log_key; 

  5. void write_to_thread_log( char const * message )
  6. {
  7.         FILE * thread_log = ( FILE * )pthread_getspecific( thread_log_key );
  8.         fprintf( thread_log, "%s/n", message );
  9. } 

  10. void close_thread_log( void * thread_log )
  11. {
  12.         fclose( ( FILE * )thread_log );
  13. } 

  14. void * thread_function( void * args )
  15. {
  16.         char thread_log_filename[ 20 ];
  17.         FILE* thread_log;
  18.         sprintf( thread_log_filename, "thread%d.log", ( int )pthread_self() );
  19.         thread_log = fopen( thread_log_filename, "w" );
  20.         pthread_setspecific( thread_log_key, thread_log );
  21.         write_to_thread_log( "Thread starting." );
  22.         return NULL;
  23. } 

  24. int main()
  25. {
  26.         int i;
  27.         pthread_t threads[5];
  28.         pthread_key_create( &thread_log_key, close_thread_log );
  29.         for ( i = 0; i < 5; ++i )
  30.         {
  31.                 pthread_create( &(threads[i]), NULL, thread_function, NULL );
  32.         }
  33.         for ( i = 0; i < 5; ++i )
  34.         {
  35.                 pthread_join( threads[i], NULL );
  36.         }
  37.         return 0;
  38. }


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