多线程
建议的体系结构:主线程创建程序所需的所有窗口,并在其中中包括所有的窗口过程,以便处理这些窗口的所有消息;其他的所有县城只进行一些后台处理,除了和主线程通讯,他们不和用户进行交流.
方法:主线程处理用户输入(和其他消息),并创建进程中的其他县城,这些附加的线程完成与用户无关的任务(UI线程 WORK线程)
线程局部存储(TLS)
CreateThread(&security_attributes, //安全令牌 一般为NULL
dwStackSize, //默认为0, windows根据需要动态延长堆栈大小
ThreadProc, //指向线程函数指针 DWORD WINAPI ThreadProc(PVOID pParam);
pParam, //传递给ThreadProc的参数
dwFlags, //通常为0, 当需要创建后不是立即执行的线程使用CREATE_SUSPENDED
&idThread) //指向接受线程ID的值变量
process.h 中声明的 hThread = _beginthread(ThreadProc, uiStackSize, pParam) 被经常使用,其中 void __cdecl ThreaProc(void* pParam),结束线程 _endthread().
临界区: CRITICAL_SECTION "互斥" 只能用于在同一个进程内的线程之间的协调
某个线程中使用: 1) InitializeCriticalSection(&cs) 2)EnterCriticalSection(&cs) 3) LevaeCriticalSection(&cs) 4)DeleteCriticalSection(&cs)
互斥对象: MUTEX 两个不同进程对同一资源的共享
事件对象:EVENT 保持一个线程在整个生存期内运行,但是只在必要时才激活它.
hevent=CreateEvent(&sa, fManual, fInitial, pszName) 其中第1,4个参数只要在事件对象被多个进程共享时才有意义,一般设置为NULL. fInitial设置事件对象的初始状态,有信号(true)和无信号(false)
置位现存事件对象 SetEvent(hevent); 复位ResetEvent(hevent)
用法:
1)创建一个事件对象
2)线程函数中调用WaitForSigleObject(hevent, dwTimeOut)判断其返回值当dwTimeOut==INFINITE时,只有事件对象被置位时才waitforsingleobject才返回,继续执行后续代码
3)如果创建时指定fManual为false,则事件对象在2)返回后被自动复位为无信号,否则应使用ResetEvent.
4)在需要线程函数执行时,调用SetEvent使事件对象置位
线程局部存储(TLS)
1)主线程调用 dwTlsIndex = TlsAlloc();
2)线程函数为数据结构分配内存,并设置索引 TlsSevValue(dwTlsIndex, GlobalAlloc(GPTR, sizeof(type))
3)使用数据 (type*)TlsGetValue(dwTlsIndex)
4)释放分配的内存 GlobalFree(TlsGetValue(dwTlsIndex))
5)使用所有数据的线程都终止时,主线程释放索引 TlsFree(dwTlsIndex);