----------------------------------------------------------------------------------------------
关键区
CRITICAL_SECTION: 定义关键区
PCRITICAL_SECTION: CRITICAL_SECTION的指针
VOID InitializeCriticalSection(PCRITICAL_SECTION pcs); 初始化关键区
VOID DeleteCriticalSection(PCRITICAL_SECTION pcs); 删除关键区
VOID EnterCriticalSection(PCRITICAL_SECTION pcs); 进入关键区
VOID LeaveCriticalSection(PCRITICAL_SECTION pcs); 离开关键区
BOOL TryEnterCriticalSection(PCRITICAL_SECTION pcs); 如果访问的资源已经被其他线程访问则返回false,反之则返回true
BOOL InitializeCriticalSectionAndSpinCount(PCRITICAL_SECTION pcs, DWORD dwSpinCount); 初始化
PCRITICAL_SECTION pcs: 关键代码段结构的地址
DWORD dwSpinCount: 在使线程等待之前它试图获得资源时想要循环锁循环迭代的次数。
为了提高关键代码段的运行性能,Microsoft将循环锁纳入了这些代码段。因此,当EnterCriticalSection函数被调用时,它就使用循环锁进行循环,以便设法多次取得该资源。
只有当为了取得该资源的每次试图都失败时,该线程才转入内核方式,以便进入等待状态。InitializeCriticalSection可能会失败,但我们不会知道。而InitializeCriticalSectionAndSpinCount若失败会返回false
DWORD SetCriticalSectionSpinCount(PCRITICAL_SECTION pcs, DWORD dwSpinCount); 设置
PCRITICAL_SECTION pcs: 关键代码段结构的地址
DWORD dwSpinCount: 在使线程等待之前它试图获得资源时想要循环锁循环迭代的次数
改变关键代码段的循环次数
----------------------------------------------------------------------------------------------
互斥对象内核对象
HANDLE CreateMutex(PSECURITY_ATTRIBUTES psa,BOOL fInitialOwner,PCTSTR pszName);
PSECURITY_ATTRIBUTES psa:
BOOL fInitialOwner:
PCTSTR pszName:
若要使用互斥对象,必须有一个进程首先调用CreateMutex,以便创建互斥对象。
HANDLE OpenMutex(DWORD fdwAccess,BOOL bInheritHandle,PCTSTR pszName);
DWORD fdwAccess:
BOOL bInheritHandle: 用于控制互斥对象的初始状态。
PCTSTR pszName:
通过调用OpenMutex,另一个进程可以获得它自己进程与现有互斥对象相关的句柄。
BOOL ReleaseMutex(HANDLE hMutex);
当目前拥有对资源的访问权的线程不再需要它的访问权时,它必须调用ReleaseMutex函数来释放该互斥对象。
如果线程ID是0(这是个无效ID),互斥对象不被任何线程所拥有,并且发出该互斥对象的通知信号。
如果ID是个非0数字,那么一个线程就拥有互斥对象,并且不发出该互斥对象的通知信号。
与所有其他内核对象不同,互斥对象在操作系统中拥有特殊的代码,允许它们违反正常的规则。
----------------------------------------------------------------------------------------------
挂起重启线程
挂起线程
DWORD SuspendThread(HANDLE hThread);
任何线程都可以调用该函数来暂停另一个线程的运行(只要拥有线程的句柄)。不用说,线程可以自行暂停运行,但是不能自行恢复运行。
与ResumeThread一样,SuspendThread返回的是线程的前一个暂停计数。线程暂停的最多次数可以是MAXIMUM_SUSPEND_COUNT次(在WinNT.h中定义为127)。
注意,SuspendThread与内核方式的执行是异步进行的,但是在线程恢复运行之前,不会发生用户方式的执行。
重启线程
DWORD ResumeThread(HANDLE hThread);
如果ResumeThread函数运行成功,它将返回线程的前一个暂停计数,否则返回0xFFFFFFFF。
单个线程可以暂停若干次。如果一个线程暂停了3次,它必须恢复3次,然后它才可以被分配给一个CPU。
----------------------------------------------------------------------------------------------
Sleep
VOID Sleep(DWORD dwMilliseconds);
该函数可使线程暂停自己的运行,直到dwMilliseconds过去为止。
关于Sleep函数,有下面几个重要问题值得注意:
1.调用Sleep,可使线程自愿放弃它剩余的时间片。
2.系统将在大约的指定毫秒数内使线程不可调度。不错,如果告诉系统,想睡眠100ms,那么可以睡眠大约这么长时间,但是也可能睡眠数秒钟或者数分钟。
记住,Windows不是个实时操作系统。虽然线程可能在规定的时间被唤醒,但是它能否做到,取决于系统中还有什么操作正在进行。
3.可以调用Sleep,并且为dwMilliseconds参数传递INFINITE。这将告诉系统永远不要调度该线程。这不是一件值得去做的事情。最好是让线程退出,并还原它的堆栈和内核对象。
4.可以将0传递给Sleep。这将告诉系统,调用线程将释放剩余的时间片,并迫使系统调度另一个线程。但是,系统可以对刚刚调用Sleep的线程重新调度。
如果不存在多个拥有相同优先级的可调度线程,就会出现这种情况。
关键区
CRITICAL_SECTION: 定义关键区
PCRITICAL_SECTION: CRITICAL_SECTION的指针
VOID InitializeCriticalSection(PCRITICAL_SECTION pcs); 初始化关键区
VOID DeleteCriticalSection(PCRITICAL_SECTION pcs); 删除关键区
VOID EnterCriticalSection(PCRITICAL_SECTION pcs); 进入关键区
VOID LeaveCriticalSection(PCRITICAL_SECTION pcs); 离开关键区
BOOL TryEnterCriticalSection(PCRITICAL_SECTION pcs); 如果访问的资源已经被其他线程访问则返回false,反之则返回true
BOOL InitializeCriticalSectionAndSpinCount(PCRITICAL_SECTION pcs, DWORD dwSpinCount); 初始化
PCRITICAL_SECTION pcs: 关键代码段结构的地址
DWORD dwSpinCount: 在使线程等待之前它试图获得资源时想要循环锁循环迭代的次数。
为了提高关键代码段的运行性能,Microsoft将循环锁纳入了这些代码段。因此,当EnterCriticalSection函数被调用时,它就使用循环锁进行循环,以便设法多次取得该资源。
只有当为了取得该资源的每次试图都失败时,该线程才转入内核方式,以便进入等待状态。InitializeCriticalSection可能会失败,但我们不会知道。而InitializeCriticalSectionAndSpinCount若失败会返回false
DWORD SetCriticalSectionSpinCount(PCRITICAL_SECTION pcs, DWORD dwSpinCount); 设置
PCRITICAL_SECTION pcs: 关键代码段结构的地址
DWORD dwSpinCount: 在使线程等待之前它试图获得资源时想要循环锁循环迭代的次数
改变关键代码段的循环次数
----------------------------------------------------------------------------------------------
互斥对象内核对象
HANDLE CreateMutex(PSECURITY_ATTRIBUTES psa,BOOL fInitialOwner,PCTSTR pszName);
PSECURITY_ATTRIBUTES psa:
BOOL fInitialOwner:
PCTSTR pszName:
若要使用互斥对象,必须有一个进程首先调用CreateMutex,以便创建互斥对象。
HANDLE OpenMutex(DWORD fdwAccess,BOOL bInheritHandle,PCTSTR pszName);
DWORD fdwAccess:
BOOL bInheritHandle: 用于控制互斥对象的初始状态。
PCTSTR pszName:
通过调用OpenMutex,另一个进程可以获得它自己进程与现有互斥对象相关的句柄。
BOOL ReleaseMutex(HANDLE hMutex);
当目前拥有对资源的访问权的线程不再需要它的访问权时,它必须调用ReleaseMutex函数来释放该互斥对象。
如果线程ID是0(这是个无效ID),互斥对象不被任何线程所拥有,并且发出该互斥对象的通知信号。
如果ID是个非0数字,那么一个线程就拥有互斥对象,并且不发出该互斥对象的通知信号。
与所有其他内核对象不同,互斥对象在操作系统中拥有特殊的代码,允许它们违反正常的规则。
----------------------------------------------------------------------------------------------
挂起重启线程
挂起线程
DWORD SuspendThread(HANDLE hThread);
任何线程都可以调用该函数来暂停另一个线程的运行(只要拥有线程的句柄)。不用说,线程可以自行暂停运行,但是不能自行恢复运行。
与ResumeThread一样,SuspendThread返回的是线程的前一个暂停计数。线程暂停的最多次数可以是MAXIMUM_SUSPEND_COUNT次(在WinNT.h中定义为127)。
注意,SuspendThread与内核方式的执行是异步进行的,但是在线程恢复运行之前,不会发生用户方式的执行。
重启线程
DWORD ResumeThread(HANDLE hThread);
如果ResumeThread函数运行成功,它将返回线程的前一个暂停计数,否则返回0xFFFFFFFF。
单个线程可以暂停若干次。如果一个线程暂停了3次,它必须恢复3次,然后它才可以被分配给一个CPU。
----------------------------------------------------------------------------------------------
Sleep
VOID Sleep(DWORD dwMilliseconds);
该函数可使线程暂停自己的运行,直到dwMilliseconds过去为止。
关于Sleep函数,有下面几个重要问题值得注意:
1.调用Sleep,可使线程自愿放弃它剩余的时间片。
2.系统将在大约的指定毫秒数内使线程不可调度。不错,如果告诉系统,想睡眠100ms,那么可以睡眠大约这么长时间,但是也可能睡眠数秒钟或者数分钟。
记住,Windows不是个实时操作系统。虽然线程可能在规定的时间被唤醒,但是它能否做到,取决于系统中还有什么操作正在进行。
3.可以调用Sleep,并且为dwMilliseconds参数传递INFINITE。这将告诉系统永远不要调度该线程。这不是一件值得去做的事情。最好是让线程退出,并还原它的堆栈和内核对象。
4.可以将0传递给Sleep。这将告诉系统,调用线程将释放剩余的时间片,并迫使系统调度另一个线程。但是,系统可以对刚刚调用Sleep的线程重新调度。
如果不存在多个拥有相同优先级的可调度线程,就会出现这种情况。