• ACE_TSS研究


    线程局部存储(TLS)在多线程编程过程中很有用.静态TLS使用方便,但不适合动态链接环境。动态TLS常用的API如下:

    DWORD TlsAlloc(void); //查找进程的线程本地存储器的位标志,返回未使用的位标志索引。PS:其返回的索引,在进程的每个线程均保留这个索引

    BOOL TlsSetValue( DWORD dwTlsIndex, LPVOID lpTlsValue );  //将一个值放入线程的线程局部存储数组

    LPVOID TlsGetValue( DWORD dwTlsIndex);     //获取线程指定索引位置的值

    BOOL TlsFree( DWORD dwTlsIndex);  //释放进程和所有线程指定位置的索引

    ACE中对线程局部存储做了封装,封装位于ACE_TSS类.该类是模板类,并重载了->和*操作符,使用起来与智能指针类似.ACE_TSS的使用示例如下:

    //线程局部变量,该变量是int类型
    ACE_TSS<int>  data;

    void  ThreadCall()
    {
        
    char  szBuffer[1024];
        
    //访问线程局部变量
        ACE_OS::sprintf( szBuffer, "当前线程ID: %d  ACE_TSS值:%d  \n"*data, ACE_Thread::self() );
        AtlTrace( szBuffer );
        ACE_OS::sleep( 
    1 );
    }

    DWORD  WorkFunc( 
    void* )
    {
        
    //设置线程局部变量为当前线程的ID
        *data  = ACE_OS::thr_self();
        ThreadCall();
        
    return 0;
    }
    .
    //创建10个线程
    ACE_Thread_Manager::instance()->spawn_n( 10, (ACE_THR_FUNC)WorkFunc, NULL, THR_NEW_LWP );
    //等待所有线程结束
    ACE_Thread_Manager::instance()->wait();

    使用起来真的很酷,完全隐藏了实现细节.跟踪ACE_TSS的实现源码,简要地分析一下实现过程:

    重载的->和*操作符都调用了成员方法ts_get,该方法首先检测是否已经从进程中分配索引,如果没有,则先调用ts_init从进程中分配索引。随后调用ACE_Thread::getspecific获取调用线程某索引处的值,如果还没有值,则调用make_TSS_TYPE分配一个指针值,make_TSS_TYPE也只是简单地调用ACE_NEW_RETURN分配动态对象.分配后调用ACE_Thread::setspecific设置到某索引处.最后值得一提的是清除工作,在析构函数中首先调用ACE_OS::thr_key_detach释放已经分配的内存指针,继而调用ACE_OS::thr_keyfree 释放进程中分配的索引值.

  • 相关阅读:
    linux环境下的makefile文件的编写(zz)
    linux 中vim的退格键的使用问题
    Design Complier Synthesis Script Templet
    Synthesis Summary 逻辑综合总结
    .net加密
    timestamp (TransactSQL) 时间戳
    ADO.NET连接池
    ASP.NET Web数据控件
    高效的读取二进制数据
    GridView
  • 原文地址:https://www.cnblogs.com/fangkm/p/1508655.html
Copyright © 2020-2023  润新知