码迷,mamicode.com
首页 > 编程语言 > 详细

[并发并行]_[C/C++]_[使用线程本地存储Thread Local Storage(TLS)调用复制文件接口的案例]

时间:2015-11-08 15:20:11      阅读:281      评论:0      收藏:0      [点我收藏+]

标签:tls   线程本地变量   pthread   win32   pthread_key_t   


使用场景:

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

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

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

2. 代码里有注释:

test.cpp

#include <iostream>

#include "pthread.h"
#include <assert.h>
#include <Windows.h>
#include <stdio.h>

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.


完整项目下载地址: 

http://download.csdn.net/detail/infoworld/9251421


版权声明:本文为博主原创文章,未经博主允许不得转载。

[并发并行]_[C/C++]_[使用线程本地存储Thread Local Storage(TLS)调用复制文件接口的案例]

标签:tls   线程本地变量   pthread   win32   pthread_key_t   

原文地址:http://blog.csdn.net/infoworld/article/details/49715355

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!