使用到了omniorb的线程库:mutex,condition variable,counting semaphores,其中包括TLS以及omni_thread的使用。
mutex:
类中有一个CRITICAL_SECTION;
构造,析构函数分别调用InitializeCriticalSection, DeleteCriticalSection
acquire, relese,函数分别调用EnterCriticalSection(&crit);LeaveCriticalSection(&crit);
condition variable:
类的构造函数中带有mutex的一个指针,用它来在wait或timewait的时候调用unlock,lock。因为condition使用信号量来调度线程间
的响应工作的。
wait(),timeWait()会使线程阻塞/超时阻塞,
signal()会唤醒至少一个正在等待的线程。
WaitForSingleObject(handle, INFINIT)返回WAIT_OBJECT_0,说明被等待的句柄有信号。
[例如:handle是__beginthreadex返回的句柄,线程结束后waitForSingleObject成功返回的结果就是WAIT_OBJECT_0]
omni_thread
构造函数中存储了用户自定义的线程函数指针,
start() -- 线程开启,通过__beginthreadex来执行线程函数所指的线程。
__beginthreadex的执行封装函数是unsigned __stdcall omni_thread_wrapper(void* ptr),ptr是omni_thread.
unsigned __stdcall omni_thread_wrapper(void* ptr)
{
...
if (me->fn_ret != NULL)
{
void* return_value = (*me->fn_ret)(me->thread_arg); --执行到自定义的线程函数。
//一旦上述线程结束,该线程通过omni_thread::exit()调用endthreadex.
omni_thread::exit(return_value);
}
...
}
join() -- 等待线程结束,如果没有结束将一直阻塞;成功等待后会将删除线程对象。
omni_semphores:
wait() -- 如果信号量为零的话,调用该函数就会阻塞,否则,信号量减一
post() -- 信号量加一,若有多个存在的线程在wait等待只会有一个线程被唤醒;如果没有线程wait则只是将信号量加一。
trywait() -- 信号量为零调用该函数不会阻塞。里面使用该函数将超时时间设置为0以立即返回。
WaitForSingleObject(nt_sem,0)
TLS 工作原理及例子 :
在review omniorb的code发现,在主线程中就会先通过TlsAlloc来得到线程局部可用的数据索引号,由于在创建新线程的时候会
将从主线程中拷贝一份同样大小的数据同时保证可用的序列号。所以新的线程无需再调用TlsAlloc,直接使用主线程得到的序列号后就可以
直接利用TlsSetValue,TlsGetValue存取线程相关的数据值了。
有关原理可以参见
http://www.cnblogs.com/zzy_cqok/archive/2009/06/15/1503805.html
为了防止连接以后不可用意外,将源码粘贴如下: