日期:2014-05-16  浏览次数:20643 次

linux线程之线程私有数据 pthread_key_create方法的学习

因为项目中需要用到主线程类共享所有数据,而主线程又要生成几个线程,而几个线程要用到主线程的数据,

 

因此每个线程要保存一个主线程类指针,类似于自己的私有资源。因此就要用到

 

用到这个类的主要是因为如果用多线程对同样的资源同步的话,就要对资源进行加锁,,,多线程就要同步

 

那么同步就会涉及到线程的切换问题,而频繁切换就会导致cpu工作压力增大,因此,根据适合的清苦啊利用适合的方法很重要。。。。

 

下面开始介绍pthread_key_create的使用

#include <pthread.h>


int pthread_key_create(pthread_key_t *key, void (*destructor)(void*)); 


 

还有

pthread_getspecific(), pthread_key_delete(),

几个函数

 

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

 

下面代码仅供学习

/**
        create by wallwind
        mail:wochenglin@qq.com
        2012/11/1

**/

#ifndef _MyTLS_h__
#define _MyTLS_h__

#include <pthread.h>

enum {NAME_SIZE =20,THREAD_NUM=10,};

//typedef DWORD pthread_key_t;

const  pthread_key_t  INVALID_PTHREAD_KEY = (pthread_key_t)0xFFFFFFFF;
//typedef void (*destory_callback)(void*);

//MyTLSPtr必须为进程全局变量,并且在初始化时直接申请key,而不是在第一次set时使用once方式来初始化key
//暂时不使用线程关闭时自动释放的方式,仍然使用谁创建谁释放的原则

class MyTLSPtr
{
public:
        MyTLSPtr():m_key(INVALID_PTHREAD_KEY)
        {
                init();
        }
        virtual ~MyTLSPtr()
        {
                destory();
        }
public:

        template< typename T >
        void set(T* pPtr)
        {
                pthread_setspecific(m_key, pPtr);
        }

        template< typename T >
        T* get() const
        {
                return static_cast<T*>(pthread_getspecific(m_key));
        }

        void init()
        {
                if(m_key != INVALID_PTHREAD_KEY)
                {
                        destory();
                }

                pthread_key_create(&m_key, NULL);
        }

        void destory()
        {
                if(m_key == INVALID_PTHREAD_KEY)
                        return;

                pthread_key_delete(m_key);

                m_key = INVALID_PTHREAD_KEY;
        }

private:
        pthread_key_t m_key;
        //destory_callback m_pCallBack;
};

template< typename T >
class MyTLSTypePtr : public MyTLSPtr
{
public:
        MyTLSTypePtr()
                :MyTLSPtr()
        {}
        virtual ~MyTLSTypePtr()
        {}

public:
        void set(T* pPtr)
        {
                MyTLSPtr::set<T>(pPtr);
        }

        T* get() const
        {
                return MyTLSPtr::get<T>();
        }
};




#endif // MyTLS_h__

 

 

使用文件

 

 
//create by wallwind mail:wochenglin@qq.com 2012/11/1
#include <malloc.h>
#include <pthread.h>
#include <stdio.h>

#include  "MyTLS.h"
//enum {NAME_SIZE =20,THREAD_NUM=10,};

MyTLSPtr g_TLS;

void write_to_thread_log (const char* message);

void* thread (void* args)
{
        char log[NAME_SIZE];
        FILE* file;
        sprintf(log,"thread_%d.log",(int)pthread_self());

        file = fopen (log, "w");
        g_TLS.set(file);

        write_to_thread_log ("message test");
}


void write_to_thread_log (const char* message)
{

        FILE* thread_log = g_TLS.get<FILE>();
        fprintf (thread_log, "%s\n", message);

}
int main()
{
        int i;
        pthread_t threads[THREAD_NUM];

        for(i = 0; i<THREAD_NUM;i++) //创建线程
                pthread_create(&threads[i],NULL,thread,NULL);

        for(i = 0;i<THREAD_NUM;i++) //主线程阻塞生成线程

                pthread_join(threads[i],NULL);
        return 0;
}


生成的文件为

 

更多文章,欢迎关注 http://blog.csdn.net/wallwind