//z 2014-05-12 11:07:22 L.233'46358 BG57IV3@XCL T3657726611.K.F1390913624[T7,L222,R4,V354]
//z 2014-05-12 10:21:38 L.233'49102 T1496279357.K[T6,L217,R4,V263]
//z 全局静态变量,所有线程共享。在线程开始之前就分配好。
static DWORD dwThreadDataTlsIndex;
//z 为线程分配 Tls slot
dwThreadDataTlsIndex = TlsAlloc();
//z tls data
typedef struct _THREADDATA
{
BOOL bReuse;
HANDLE hEvent;
LONG volatile lBlockingCount;
LPOUTPUT_THEME lpTheme;
INT32 iAutoTheme;
struct _FTP_USER *lpFtpUser;
struct _THREADDATA *lpNext, *lpPrev;
LPRESOURCE_DTOR lpDestructor;
} THREADDATA, *LPTHREADDATA;
//z 创建 worker thread,为各个线程分配配置 tls data
LPTHREADDATA lpThreadData;
lpThreadData = Allocate("Thread:Data", sizeof(THREADDATA));
ZeroMemory(lpThreadData, sizeof(*lpThreadData));
//z 创建 worker thread 线程。
hThread = CreateThread(NULL, 0,(LPTHREAD_START_ROUTINE)WorkerThread, lpThreadData, 0, &dwThreadId);
// Store TLS data
TlsSetValue(dwThreadDataTlsIndex, lpThreadData);
//z 使用 tls data 的例子
LPOUTPUT_THEME GetTheme()
{
LPTHREADDATA lpThreadData;
lpThreadData = (LPTHREADDATA)TlsGetValue(dwThreadDataTlsIndex);
if (!lpThreadData) return NULL;
return lpThreadData->lpTheme;
}
VOID SetFtpUser(LPFTPUSER lpFtpUser)
{
LPTHREADDATA lpThreadData;
lpThreadData = (LPTHREADDATA)TlsGetValue(dwThreadDataTlsIndex);
if (!lpThreadData) return;
lpThreadData->lpFtpUser = lpFtpUser;
}
LPFTPUSER GetFtpUser()
{
LPTHREADDATA lpThreadData;
lpThreadData = (LPTHREADDATA)TlsGetValue(dwThreadDataTlsIndex);
if (!lpThreadData) return NULL;
return lpThreadData->lpFtpUser;
}
//z 使用完毕,清理tls资源。
lpThreadData = (LPTHREADDATA)TlsGetValue(dwThreadDataTlsIndex);
if (lpThreadData)
{
Free(lpThreadData);
}
TlsFree(dwThreadDataTlsIndex);
//z ioftpd 使用了 thread pool (线程池)的方式,在等待 job 时,各个线程使用的等待时间为:
//z GetCurrentThreadId() 得到当前线程的 id
//z The CreateFiber and ConvertThreadToFiber functions return the fiber address when the fiber is created.
//z The GetCurrentFiber macro allows you to retrieve the address at any other time.
//z GetTickCount()系统启动后所经历的时间
// Set random seed
srand(GetCurrentThreadId() + GetTickCount() + (DWORD)GetCurrentFiber());
// use a delay of between 5 and 10 seconds
dwDelay = (DWORD) ((double)rand() / (RAND_MAX + 1) * 5000 + 5000);
来自微软的例子
Using Thread Local Storage
Thread local storage (TLS) enables multiple threads of the same process to use an index allocated by the TlsAlloc function to store and retrieve a value that is local to the thread. In this example, an index is allocated when the process starts. When each thread starts, it allocates a block of dynamic memory and stores a pointer to this memory in the TLS slot using the TlsSetValue function. The CommonFunc function uses the TlsGetValue function to access the data associated with the index that is local to the calling thread. Before each thread terminates, it releases its dynamic memory. Before the process terminates, it calls TlsFree to release the index.
#include <windows.h>
#include <stdio.h>
#define THREADCOUNT 4
DWORD dwTlsIndex;
VOID ErrorExit(LPSTR);
VOID CommonFunc(VOID)
{
LPVOID lpvData;
// Retrieve a data pointer for the current thread.
lpvData = TlsGetValue(dwTlsIndex);
if ((lpvData == 0) && (GetLastError() != ERROR_SUCCESS))
ErrorExit("TlsGetValue error");
// Use the data stored for the current thread.
printf("common: thread %d: lpvData=%lx\n",
GetCurrentThreadId(), lpvData);
Sleep(5000);
}
DWORD WINAPI ThreadFunc(VOID)
{
LPVOID lpvData;
// Initialize the TLS index for this thread.
lpvData = (LPVOID) LocalAlloc(LPTR, 256);
if (! TlsSetValue(dwTlsIndex, lpvData))
ErrorExit("TlsSetValue error");
printf("thread %d: lpvData=%lx\n", GetCurrentThreadId(), lpvData);
CommonFunc();
// Release the dynamic memory before the thread returns.
lpvData = TlsGetValue(dwTlsIndex);
if (lpvData != 0)
LocalFree((HLOCAL) lpvData);
return 0;
}
int main(VOID)
{
DWORD IDThread;
HANDLE hThread[THREADCOUNT];
int i;
// Allocate a TLS index.
if ((dwTlsIndex = TlsAlloc()) == TLS_OUT_OF_INDEXES)
ErrorExit("TlsAlloc failed");
// Create multiple threads.
for (i = 0; i < THREADCOUNT; i++)
{
hThread[i] = CreateThread(NULL, // default security attributes
0, // use default stack size
(LPTHREAD_START_ROUTINE) ThreadFunc, // thread function
NULL, // no thread function argument
0, // use default creation flags
&IDThread); // returns thread identifier
// Check the return value for success.
if (hThread[i] == NULL)
ErrorExit("CreateThread error\n");
}
for (i = 0; i < THREADCOUNT; i++)
WaitForSingleObject(hThread[i], INFINITE);
TlsFree(dwTlsIndex);
return 0;
}
VOID ErrorExit (LPSTR lpszMessage)
{
fprintf(stderr, "%s\n", lpszMessage);
ExitProcess(0);
}
//另一个例子
//TlsDemo.c
//compile:cl.exe TlsDemo.c
//下面注释为其执行顺序
#include <windows.h>
DWORD g_dwTlsIndex = -1;
unsigned TlsProc1(void *unuse)
{
LPVOID lpValue = NULL;
TlsSetValue(g_dwTlsIndex,(PVOID)1234);//2
Sleep(1000);
lpValue = TlsGetValue(g_dwTlsIndex); //5
printf("TlsProc1:%d/n",(DWORD)lpValue);
return 0;
}
unsigned TlsProc2(void *unuse)
{
LPVOID lpValue = NULL;
TlsSetValue(g_dwTlsIndex,(PVOID)4567);//3
lpValue = TlsGetValue(g_dwTlsIndex); //4
printf("TlsProc2:%d/n",(DWORD)lpValue);
return 0;
}
int main(void)
{
g_dwTlsIndex = TlsAlloc(); // 1
_beginthreadex(NULL,0,TlsProc1,NULL,0,NULL);
_beginthreadex(NULL,0,TlsProc2,NULL,0,NULL);
_getch();
TlsFree(g_dwTlsIndex);
}
静态TLS使用__declspec(thread)修饰符声明全局或静态(static)的TLS变量,TLS变量将被编译器放到.tls段中。
系统在载入应用程序时,将根据.tls段的大小分配足够的内存来保存所有的静态TLS变量。若进程新建了一个线程,那么系统也要为新线程分配一样大的内存来保存的静态TLS变量。如果在加载一个DLL时,DLL中也存在静态TLS变量,那么系统会为进程中的所有线程扩展其TLS的内存容量。如果卸载一个DLL时,DLL中存在静态TLS变量,那么系统会为进程中的所有线程缩减其TLS的内存容量。(P571)
//z 2014-05-12 11:53:10 L.233’43610 BG57IV3@XCL T3557450373.K.F1390913624[T9,L474,R4,V384]
//TlsDemo.c
//compile:cl.exe TlsDemo.c
//下面注释为其执行顺序
#include <windows.h>
__declspec(thread) DWORD g_dwTlsValue = 0;
unsigned TlsProc1(void *unuse)
{
g_dwTlsValue = 0x12345678; // 1
Sleep(1000);
printf("TlsProc1:0x%08x/n",g_dwTlsValue); //4
return 0;
}
unsigned TlsProc2(void *unuse)
{
g_dwTlsValue = 0x87654321; //2
printf("TlsProc2:0x%08x/n",g_dwTlsValue);//3
return 0;
}
int main(void)
{
_beginthreadex(NULL,0,TlsProc1,NULL,0,NULL);
_beginthreadex(NULL,0,TlsProc2,NULL,0,NULL);
_getch();
}
//z 2014-05-12 11:53:10 L.233’43610 BG57IV3@XCL T3557450373.K.F1390913624[T9,L474,R4,V384]
转载于:https://www.cnblogs.com/IS2120/p/6745660.html
今天的文章ioftpd 之 tls分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/24211.html