当前位置: 首页 > news >正文

ioftpd 之 tls

//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 attributes0,                           // use default stack size(LPTHREAD_START_ROUTINE) ThreadFunc, // thread functionNULL,                    // no thread function argument0,                       // 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);//2Sleep(1000);lpValue = TlsGetValue(g_dwTlsIndex);  //5printf("TlsProc1:%d/n",(DWORD)lpValue);return 0;
}unsigned TlsProc2(void *unuse)
{LPVOID lpValue = NULL;TlsSetValue(g_dwTlsIndex,(PVOID)4567);//3lpValue = TlsGetValue(g_dwTlsIndex);  //4printf("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;  // 1Sleep(1000);printf("TlsProc1:0x%08x/n",g_dwTlsValue); //4return 0;
}unsigned TlsProc2(void *unuse)
{g_dwTlsValue = 0x87654321;   //2printf("TlsProc2:0x%08x/n",g_dwTlsValue);//3return 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

http://www.lryc.cn/news/570833.html

相关文章:

  • HTTP协议简易入门
  • Velocity提取模板变量
  • php小偷程序实例代码
  • JavaWeb(cekditorsmartupload)
  • Asp.Net的简介
  • 安 利的骗局与真相,关于美国安 利的真实情况
  • 电磁场与电磁波篇---介质媒质导体
  • java实现分页数据每页按比率展示不同类型的数据
  • [转]Visual Studio 各版本区别
  • JDK和JRE官方下载地址
  • 操作系统期末复习整理知识点+习题练习
  • PHP基础篇:empty() 和 isset() 的区别介绍
  • 使用STM32的FLASH保存数据
  • HashiCorp Vault核心应用场景深度解析,国产化替代有什么备选方案
  • JDK1.6官方下载 JDK6官方下载地址
  • C# 取消按钮焦点 (非自定义控件)
  • C# DataTable 自动新增列并赋值
  • 优秀国外博客推荐
  • 史上最全的CSS hack方式一览
  • 第三方登录微信登录流程
  • 各种游戏搬砖ip工具,刷数据IP工具介绍
  • 彻底解决快播不可点播方法
  • 借网上盛传2000w记录介绍多进程处理
  • 启动应用程序出现taskmgr.exe找不到问题解决
  • 使用Garageband给iPhone设置铃声
  • Intel, AMD及VIA CPU的微架构(36)
  • Linux入门(十五)jq 命令解析JSON的安装、使用
  • BeckHoff <---> sartorius天平 采用 EL6002 (RS232)串口通讯
  • 网络端口号大全(附服务说明)
  • 硅钢片知识点