win32(十五)

来源:互联网 发布:淘宝怎么用余额宝分期 编辑:程序博客网 时间:2024/05/17 06:13
一 线程局部存储 Thread Local Storage  1 由于多个线程使用同一个变量,各个线程    都对变量进行操作,那么变量的值会被不同    线程操作覆盖。      通常   变量A   <-- 线程A                     <-- 线程B      TLS    变量A   <-- 线程A             变量A   <-- 线程B   2 TLS的使用     2.1 使用关键字 __declspec(thread)         __declspec(thread) CHAR * g_pszText2 = NULL;     2.2 TLS相关API       2.2.1 创建TLS索引         DWORD TlsAlloc(VOID)         返回一个TLS索引号       2.2.2 设置值         BOOL TlsSetValue(         DWORD dwTlsIndex, //TLS索引         LPVOID lpTlsValue //保存的值         );       2.2.3 获取值         LPVOID TlsGetValue(          DWORD dwTlsIndex  //TLS索引         );         返回存放在索引内的值       2.2.4 释放         BOOL TlsFree(          DWORD dwTlsIndex   //TLS索引         );二 线程同步  1 多线程的问题    A停止 -> B开始 -〉B停止 -> A开始     当线程停止会保存寄存器的状态。     当线程开始会恢复寄存器的状态。    AB线程都使用printf的问题:    A线程调用printf时,printf正在输出    当中,A挂起,B执行,B线程也调用    printf输出B的数据,画面会出现A的    数据输出1部分,然后是B的数据;    B挂起,A执行, A继续输出自己的数据.    所以,由于多线程的切换,产生数据混乱.  2 问题的解决 - 同步机制    2.1 原子锁    2.2 临界区    2.3 事件    2.4 互斥    2.5 信号量    2.6 可等候定时器  3 等候多个内核对象事件    DWORD WaitForMultipleObjects(     DWORD nCount,//句柄的数量     CONST HANDLE *lpHandles,//句柄数组     BOOL fWaitAll, //等候方式    DWORD dwMilliseconds );//等候时间    等候方式fWaitAll:       TRUE - 每个句柄都有事件,解除阻塞       FALSE - 其中一个句柄有事件,解除阻塞三 原子锁  1 g_nValue++执行    线程A通过寄存器完成加法运算,假设    g_nValue正在加到10000时,线程切换到B,    A的寄存器中保存10000数字,B从10000    开始加数据,当B加到15000时,线程切换    到A,A恢复寄存器的值,A会继续从10000开始    累加,就将B完成5000的加法覆盖.  2 原子锁    执行单个指令时,锁定操作,不允许其他    线程访问.  3 用法    InterlockedIncrement ++运算    InterlockedDecrement --运算    InterlockedCompareExchange ?运算四 临界区  1 临界区作用    线程在执行代码时,将代码锁定,不允    许其他线程执行,只有该线程离开后,    其他线程才能使用这些代码  2 临界区的使用    2.1 初始化临界区       VOID InitializeCriticalSection(       LPCRITICAL_SECTION lpCriticalSection         //临界区结构地址       );    2.2 临界区加锁       VOID EnterCriticalSection(            LPCRITICAL_SECTION lpCriticalSection   // pointer to critical           //临界区            );    2.3 临界区解锁       VOID LeaveCriticalSection(       LPCRITICAL_SECTION lpCriticalSection           // 临界区        );    2.4 释放临界区       VOID DeleteCriticalSection(       LPCRITICAL_SECTION lpCriticalSection                  //临界区       );  3 和原子锁相比    原子锁是一条语句    临界区可以完成多条语句的锁定.五 事件  1 事件    通知的作用,当收到事件时,线程可以执行.    否则,线程将等候事件发生.  2 事件的用法    2.1 创建事件            HANDLE CreateEvent(       LPSECURITY_ATTRIBUTES lpEventAttributes,                      //安全属性       BOOL bManualReset,//重置方式       BOOL bInitialState, //初始化状态       LPCTSTR lpName //名称             );            返回创建好的事件句柄            bManualReset - 事件重置方式, TRUE              手动和FALSE自动重置. 如果为FALSE,              系统在等候到事件后,会自动将事件              重置为无信号状态. 如果为TRUE,我们              必须自己使用ResetEvent重置状态.      bInitialState - 初始化状态, TRUE为         有信号,FALSE无信号.   2.2 等候事件      WaitForSingleObject/      WaitForMultipleObjects    2.3 触发事件      BOOL SetEvent(      HANDLE hEvent //事件句柄      );    2.4 关闭事件      CloseHandle    2.5 重置事件      BOOL ResetEvent(       HANDLE hEvent //事件句柄      );    2.6 其他函数      OpenEvent      PulseEvent六 互斥量   1 互斥量    多个线程同时只能有一个执行.  2 互斥量使用    2.1 创建互斥      HANDLE CreateMutex(        LPSECURITY_ATTRIBUTES lpMutexAttributes,                       //安全属性        BOOL bInitialOwner,                         //初始化的拥有线程            LPCTSTR lpName ); //名称            bInitialOwner - TRUE表示当前创建互斥             量的线程拥有互斥, FALSE为不拥有.    2.2 等候互斥       WaitForSingleObject       WaitForMultipleObjects    2.3 重置互斥       ReleaseMutex     2.4 关闭互斥       CloseHandle    2.5 使用互斥线程,按照谁先等候谁先       拥有互斥量的规则顺序执行.    2.6 其他函数      OpenMutex 打开互斥七 信号量  1 信号量    通知的作用,和事件类似.但是与事件不同.    事件只维护一个值0或者1.    信号量维护一个变量,0时无信号,大于0有    信号.  2 信号量的使用    2.1 创建信号量        HANDLE CreateSemaphore(       LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,                       //安全属性       LONG lInitialCount,//初始信号量       LONG lMaximumCount,//最大信号量       LPCTSTR lpName //命名        );      返回创建好的信号量句柄.    2.2 等候信号量      WaitForSingleObject      WaitForMultipleObjects    2.3 释放信号      BOOL ReleaseSemaphore(       HANDLE hSemaphore, //信号量句柄       LONG lReleaseCount,//释放信号的数量       LPLONG lpPreviousCount //释放前的数量      );    2.4 关闭信号量      CloseHandle    2.5 打开信号量      OpenSemaphore八 可等候定时器  1 可等候定时器    是一个更加精确系统提供的定时器.能够    达到100ns级别.   2 定时器的使用    2.1 创建定时器        HANDLE CreateWaitableTimer(      LPSECURITY_ATTRIBUTES lpTimerAttributes,                      //安全属性      BOOL bManualReset,//重置方式      LPCTSTR lpTimerName //命名      );      返回创建好的定时器的句柄    2.2 设置定时器      BOOL SetWaitableTimer(       HANDLE hTimer, //定时器句柄       const LARGE_INTEGER *pDueTime,        //定时器第一次触发的时间,100ns级别       LONG lPeriod,         //后续每次触发的间隔,毫秒级别       PTIMERAPCROUTINE pfnCompletionRoutine,          //APC处理函数       LPVOID lpArgToCompletionRoutine,        //APC参数       BOOL fResume ); //休眠标识       pDueTime - 正值,表示绝对时间          负值,表示相对于现在的时间间隔       lPeriod  - 0  定时器不再有后续触发          大于0 按照间隔触发       pDueTime | lPeriod | lPeriod ....    2.3 等候定时器      WaitForSingleObject      WaitForMultipleObjects    2.4 关闭定时器      CloseHandle    2.5 APC定时器      VOID CALLBACK TimerAPCProc(      LPVOID lpArgToCompletionRoutine   // data value      DWORD dwTimerLowValue // timer low value      DWORD dwTimerHighValue   // timer high value          );        2.6 其他          OpenWaitableTimer 打开          CancelWaitableTimer 取消
0 0
原创粉丝点击