ncnn 线程

本文详细介绍了Windows平台上线程类和线程局部存储(TLS)的实现,包括线程的创建、join操作以及TLS的分配、设置和获取。同时,提到了线程同步的Mutex和ConditionVariable的使用,解释了它们在多线程编程中的作用。此外,还阐述了线程的状态和同步方式。
摘要由CSDN通过智能技术生成

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函数用法_心情第一的博客-CSDN博客_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_宇文莺语的博客-CSDN博客

线程条件变量:线程同步 条件变量 CONDITION_VARIABLE 用户模式同步对象 InitializeConditionVariable_宇文莺语的博客-CSDN博客_sleepconditionvariablecs

线程状态:新建状态、就绪态、运行、阻塞、死亡

线程同步方式:C++线程同步的四种方式(Windows) - 华丽的双鱼 - 博客园

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

HySmiley

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值