频道栏目
首页 > 程序开发 > 软件开发 > C++ > 正文
[并发并行]_[C/C++]_[使用线程本地存储Thread Local Storage(TLS)调用复制文件接口的案例]
2015-11-08 10:01:42         来源:心如止水  
收藏   我要投稿

 

使用场景:

1. 在复制文件时,一般都是一个线程调用一个接口复制文件,这时候需要缓存数据,如果每个文件都需要创建独立的缓存,那么内存碎片是很大的.

如果创建一个static的内存区,当多线程调用同一个接口时,多个线程同时使用同一个static缓存会造成数据污染.最好的办法是这个缓存只对这个线程可见,

当线程创建时创建缓存区,当线程结束时销毁缓存区.

2. 代码里有注释:

test.cpp

 

#include 

#include pthread.h
#include 
#include 
#include 

typedef enum kTLSKey1
{
	kTLSKeyCopyFileBuf = 0,
	kTLSKeyOthers,
	kTLSKeyMax
}kTLSKey;

static pthread_key_t gTLSKey[kTLSKeyMax];
static int gTLSKeySize[kTLSKeyMax] = {4194304,4096};

// 这个只是测试等待线程全部结束用的,和TLS没什么关系.
static pthread_barrier_t barrier  = NULL; 
static int THREADCOUNT = 10;

// 我们自定义的库提供的接口1
void StartWork(kTLSKey type)
{
	pthread_key_t& key = gTLSKey[type];
	pthread_key_create(&key,NULL);
}

// 我们自定义的库提供的接口2
void EndWork(kTLSKey type)
{
	pthread_key_t& key = gTLSKey[type];
	pthread_key_delete(key);
}

// 我们自定义的库提供的接口3
// data参数只是为了证明TLS的变量是绑定线程的.
void MyCopyFile(const char* from, const char* to,void* data)
{
	pthread_key_t& key = gTLSKey[kTLSKeyCopyFileBuf];
	char* lpvData = (char*)pthread_getspecific(key);
	assert(lpvData == data);

	Sleep(100);

}

void* ThreadFunc(void* data)
{
	int size = gTLSKeySize[kTLSKeyCopyFileBuf];
	pthread_key_t& key = gTLSKey[kTLSKeyCopyFileBuf];

	char* buf = (char*)malloc(size);
	std::cout << GetCurrentThreadId() << Create buf size:  << size << : << (int*)buf << std::endl;
	pthread_setspecific(key, buf); // 申请的内存存放到TLS里.

	// 每个线程复制100个文件
	for (int i = 0; i < 100; ++i)
	{
		MyCopyFile(C:\infoworld.txt,E:\infoworld.txt,buf);
	}
	
	free(buf);
	std::cout << ThreadFunc:  << GetCurrentThreadId() <<  finish << std::endl;
	pthread_barrier_wait(&barrier);
	return NULL;
}

void TestPthreadLocalStorage()
{
	StartWork(kTLSKeyCopyFileBuf); // 在主程序初始化.
	pthread_barrier_init(&barrier,NULL, THREADCOUNT+1); // 主线程也是,所以+1

	// 模拟 THREADCOUNT 个线程同时调用接口 MyCopyFile.
	for (int i = 0; i < THREADCOUNT; ++i)
	{
		pthread_t t;  
        pthread_create(&t,NULL,ThreadFunc,NULL);  
        pthread_detach(t);
	}

	pthread_barrier_wait(&barrier);
	EndWork(kTLSKeyCopyFileBuf); // 在主程序释放.
}

int main(int argc, char const *argv[])
{
	setvbuf(stdout,NULL,_IONBF,0);
	std::cout << test thread local storage. << std::endl;
	TestPthreadLocalStorage();
	std::cout << end thread local storage. << std::endl;

	return 0;
}

 

 

输出:

 

test thread local storage.
5168 Create buf size: 4194304:0x1180020
3892 Create buf size: 4194304:0x1790020
3352 Create buf size: 4194304:0x21a0020
5808 Create buf size: 4194304:0x29b0020
4972 Create buf size: 4194304:0x2dc0020
6812 Create buf size: 4194304:0x31d0020
6132 Create buf size: 4194304:52200x35e0020 Create buf size: 
4194304:0x39f0020
6124 Create buf size: 4194304:0x3e00020
6864 Create buf size: 4194304:0x4210020
ThreadFunc: 5168 finish
ThreadFunc: 3892 finish
ThreadFunc: 6812 finish
ThreadFunc: 5220 finish
ThreadFunc: 4972 finish
ThreadFunc: 6132 finish
ThreadFunc: 6864 finish
ThreadFunc: 3352 finish
ThreadFunc: 5808 finish
ThreadFunc: 6124 finish
end thread local storage.

 

 
点击复制链接 与好友分享!回本站首页
上一篇:[LeetCode从零单刷]Longest Increasing Subsequence
下一篇:[LeetCode] Missing Number
相关文章
图文推荐
点击排行

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站