[考古贴]线程本地化存储(Thread Local Storage)示例2则

以下的描述及示例摘录自网上,但其内容经过了整理和编辑。

“Thread Local Storage的功用是什么呢?它主要是为了避免多个线程同时访存同一全局变量或者静态变量时所导致的冲突,尤其是多个线程同时需要修改这一变量时。为了解决这个问题,我们可以通过TLS机制,为每一个使用该全局变量的线程都提供一个变量值的副本,每一个线程均可以独立地改变自己的副本,而不会和其它线程的副本冲突。从线程的角度看,就好像每一个线程都完全拥有该变量。而从全局变量的角度上来看,就好像一个全局变量被克隆成了多份副本,而每一份副本都可以被一个线程独立地改变。”

“TLS也可以用于线程同步机制,它能够被用来解决多线程中的对同一变量的访问冲突。在普通的同步机制中,是通过对象加锁来实现多个线程对同一变量的安全访问的。这时该变量是多个线程共享的,使用这种同步机制需要很细致地分析在什么时候对变量进行读写,什么时候需要锁定某个对象,什么时候释放该对象的锁等等很多。所有这些都是因为多个线程共享了资源造成的,同时,加同步锁也是一个可能会影响性能的瓶颈。TLS从另一个角度来解决多线程的并发访问,它为每一个线程维护一个和该线程绑定的变量的副本,从而隔离了多个线程的数据,每一个线程都拥有自己的变量副本,因而也就没有必要对该变量进行同步了。TLS提供了线程安全的共享对象,在编写多线程代码时,可以把不安全的整个变量封装进TLS,或者把该对象的特定于线程的状态封装进TLS。”

示例1:直接利用Win32 API实现TLS
ContractedBlock.gif ExpandedBlockStart.gif 直接利用Win32 API实现TLS
None.gif#include "stdafx.h"
None.gif#include
"windows.h"
None.gif#include
"iostream"
None.gif
None.gif
using namespace std;
None.gif
ExpandedBlockStart.gifContractedBlock.giftypedef 
struct dot.gif{
InBlock.gif    DWORD dwFrequency;
InBlock.gif    DWORD dwDuration;
ExpandedBlockEnd.gif}
 soundParams;
None.gif
None.gifDWORD g_nTlsIndex; 
//!!
None.gif

None.gif
void ParamsAlloc()
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif    soundParams 
*params;
InBlock.gif    
params=(soundParams*)new soundParams;        
InBlock.gif    
InBlock.gif    
params->dwFrequency=GetTickCount() & 0x00000FFF;
InBlock.gif    
params->dwDuration=100;
InBlock.gif
InBlock.gif    cout
<<"使用频率:"<<params->dwFrequency<<"\t延时:"<<params->dwDuration<<endl;
InBlock.gif
InBlock.gif    TlsSetValue(g_nTlsIndex,
params); //!!
ExpandedBlockEnd.gif
}

None.gif
None.gif
void ParamsFree()
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif    soundParams 
*params;
InBlock.gif    
params=(soundParams*)TlsGetValue(g_nTlsIndex); //!!
InBlock.gif

InBlock.gif    delete 
params;
ExpandedBlockEnd.gif}

None.gif
None.gif
void ToBeep(void)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif    soundParams 
*params;
InBlock.gif    
params=(soundParams*)TlsGetValue(g_nTlsIndex); //!!
InBlock.gif
    ::Beep(params->dwFrequency,params->dwDuration);
ExpandedBlockEnd.gif}

None.gif
None.gif
void SoundThread()
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif    ParamsAlloc();
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
for (DWORD i=0;i<8;i++dot.gif{
InBlock.gif        ToBeep();
InBlock.gif        Sleep(
1000);
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    ParamsFree();
ExpandedBlockEnd.gif}

None.gif
None.gif
int _tmain(int argc,_TCHAR *argv[])
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif    HANDLE soundHandles[
3];
InBlock.gif    DWORD dwThreadID;
InBlock.gif    DWORD dwCount;
InBlock.gif
InBlock.gif    g_nTlsIndex
=TlsAlloc(); //!!
InBlock.gif
    
ExpandedSubBlockStart.gifContractedSubBlock.gif    
for(dwCount=0;dwCount<3;dwCount++dot.gif{
InBlock.gif        soundHandles[dwCount]
=CreateThread(NULL,0,
InBlock.gif            (LPTHREAD_START_ROUTINE)SoundThread,
0,0,
InBlock.gif            
&dwThreadID);
InBlock.gif
InBlock.gif        Sleep(
1500);
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    WaitForMultipleObjects(
3,soundHandles,TRUE,INFINITE);
InBlock.gif
InBlock.gif    TlsFree(g_nTlsIndex); 
//!!
InBlock.gif

InBlock.gif    
return 0;
ExpandedBlockEnd.gif}

示例2:使用编译器支持实现TLS
ContractedBlock.gif ExpandedBlockStart.gif 利用编译器支持实现TLS
None.gif#include "stdafx.h"
None.gif#include
"windows.h"
None.gif#include
"iostream"
None.gif
None.gif
using namespace std;
None.gif
ExpandedBlockStart.gifContractedBlock.giftypedef 
struct dot.gif{
InBlock.gif    DWORD dwFrequency;
InBlock.gif    DWORD dwDuration;
ExpandedBlockEnd.gif}
 soundParams;
None.gif
None.gif__declspec(thread) soundParams 
*g_pParams; //!!
None.gif

None.gif
void SoundThread()
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif    g_pParams
=(soundParams*)new soundParams;
InBlock.gif    g_pParams
->dwFrequency=GetTickCount() & 0x00000FFF;
InBlock.gif    g_pParams
->dwDuration=100;
InBlock.gif
InBlock.gif    cout
<<"使用频率:"<<g_pParams->dwFrequency<<"\t延时:"<<g_pParams->dwDuration<<endl;
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
for(DWORD i=0;i<8;i++dot.gif{
InBlock.gif        ::Beep(g_pParams
->dwFrequency,g_pParams->dwDuration);
InBlock.gif        Sleep(
1000);
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    delete g_pParams;
ExpandedBlockEnd.gif}

None.gif
None.gif
int _tmain(int argc,_TCHAR *argv[])
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif    HANDLE soundHandles[
3];
InBlock.gif    DWORD dwThreadID;
InBlock.gif    DWORD dwCount;
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
for (dwCount=0;dwCount<3;dwCount++dot.gif{
InBlock.gif        soundHandles[dwCount]
=CreateThread(NULL,0,
InBlock.gif            (LPTHREAD_START_ROUTINE)SoundThread,
0,0,
InBlock.gif            
&dwThreadID);
InBlock.gif
InBlock.gif        Sleep(
1500);
ExpandedSubBlockEnd.gif    }

InBlock.gif
InBlock.gif    WaitForMultipleObjects(
3,soundHandles,TRUE,INFINITE);
InBlock.gif
InBlock.gif    
return 0;
ExpandedBlockEnd.gif}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值