ncnn-platform.h
线程与线程局部存储类的创建-声明及实现
static unsigned __stdcall start_wrapper(void* args);
//线程类
class NCNN_EXPORT Thread
{
public:
//构造函数-初始化列表
Thread(void* (*start)(void*), void* args = 0) { _start = start; _args = args; handle = (HANDLE)_beginthreadex(0, 0, start_wrapper, this, 0, 0); }
~Thread() {}
//join实现-调用线程等待该线程完成后,才能继续往下运行
void join() { WaitForSingleObject(handle, INFINITE); CloseHandle(handle); }
private:
friend unsigned __stdcall start_wrapper(void* args)
{
Thread* t = (Thread*)args;
t->_start(t->_args);
return 0;
}
HANDLE handle;
void* (*_start)(void*);
void* _args;
};
//线程局部存储(TLS)
class NCNN_EXPORT ThreadLocalStorage
{
public:
ThreadLocalStorage() { key = TlsAlloc(); }
~ThreadLocalStorage() { TlsFree(key); }
void set(void* value) { TlsSetValue(key, (LPVOID)value); }
void* get() { return (void*)TlsGetValue(key); }
private:
DWORD key;
};
WaitForSingleObject(handle, INFINITE); CloseHandle(handle);
等待一个内核对象变为已通知状态。
该函数需要传递一个内核对象句柄,该句柄标识一个内核对象,如果该内核对象处于未通知状态,则该函数导致线程进入阻塞状态;如果该内核对象处于已通知状态,则该函数立即返回WAIT_OBJECT_0。第二个参数指明了需要等待的时间(毫秒),可以传递INFINITE指明要无限期等待下去,如果第二个参数为0,那么函数就测试同步对象的状态并立即返回。如果等待超时,该函数返回WAIT_TIMEOUT。如果该函数失败,返回WAIT_FAILED。
WaitForSingleObject函数用法_心情第一的博客-优快云博客_waitforsingleobject函数
TLS参考:TLS--线程局部存储 - tungli - 博客园
动态TLS
系统中每个进程都有一组正在使用标志(in-use flags),每个标志可以被设为FREE或INUSE,表示该TLS元素是否正在被使用。
一般通过调用一组4个API函数来使用动态TLS:TlsAlloc、TlsSetValue、TlsGetValue和TlsFree。
1)要使用动态TLS,必须先调用TlsAlloc函数:
DWORD WINAPI TlsAlloc(void);
2)为了把一个值放到线程的PVOID数组中,应该调用TlsSetValue函数:
BOOL WINAPI TlsSetValue(
__in DWORD dwTlsIndex, //索引值,表示在数组中的具体位置
__in_opt LPVOID lpTlsValue //要设置的值
);
3)为了从线程的数组中取回一个值,应该调用函数TlsGetValue:
LPVOID WINAPI TlsGetValue(
__in DWORD dwTlsIndex //索引值
);
4)当不再需要一个已经预定的TLS元素时,应该调用TlsFree函数:
BOOL WINAPI TlsFree(
__in DWORD dwTlsIndex //索引值
);
Mutex类与ConditionVariable声明-线程同步 读写锁/条件变量
互斥量防止多个线程同时访问同一个共享变量。
条件变量就允许一个线程就某个共享变量的状态变化通知其他线程,并让其他线程等待于这一通知。
条件变量与互斥量通常一起使用,原因是线程在因条件未满足而阻塞并等待前,需要访问“条件”,而“条件”是允许其它线程修改的,因此,访问“条件”时需要加锁,访问结束后释放锁。
class NCNN_EXPORT Mutex
{
public:
Mutex() { InitializeSRWLock(&srwlock); }//初始化读写锁
~Mutex() {}
void lock() { AcquireSRWLockExclusive(&srwlock); }//独占式访问
void unlock() { ReleaseSRWLockExclusive(&srwlock); }//独占式释放
private:
friend class ConditionVariable;//友元条件变量类
// NOTE SRWLock is available from windows vista
SRWLOCK srwlock;
};
class NCNN_EXPORT ConditionVariable
{
public:
ConditionVariable() { InitializeConditionVariable(&condvar); }//初始化条件变量
~ConditionVariable() {}
void wait(Mutex& mutex) { SleepConditionVariableSRW(&condvar, &mutex.srwlock, INFINITE, 0); }//解锁SRWLock,等待CV,函数返回后,自动加锁SRWLock
void broadcast() { WakeAllConditionVariable(&condvar); }//唤醒所有等待条件变量的线程
void signal() { WakeConditionVariable(&condvar); }//唤醒一个等待条件变量的线程
private:
CONDITION_VARIABLE condvar;
};
线程同步:线程同步 Slim读写锁 SRWLOCK 用户模式同步对象 InitializeSRWLock_宇文莺语的博客-优快云博客
线程状态:新建状态、就绪态、运行、阻塞、死亡