1、相关文件和接口
#include <windows.h> CRITICAL_SECTION cs;//定义临界区对象 InitializeCriticalSection(&cs);//初始化临界区 EnterCriticalSection(&cs);//进入临界区 LeaveCriticalSection(&cs);//离开临界区 DeleteCriticalSection(&cs);//删除临界区
2、测试代码
#include <Windows.h> #include <string> #include <iostream> CRITICAL_SECTION cs; DWORD WINAPI Fun(LPVOID lpParamter) { std::string strPrint((const char*)lpParamter); int iRunTime = 0; while(++iRunTime<10) { EnterCriticalSection(&cs); std::cout <<"["<< iRunTime <<"]:"<< strPrint.c_str()<<std::endl; LeaveCriticalSection(&cs); Sleep(1); //离开临界区后线程进行休眠,其它线程进入临界区的概率大大降低,所以需要短暂休眠。 } return 0; } int _tmain(int argc, _TCHAR* argv[]) { InitializeCriticalSection(&cs); //创建五个子线程 std::string str1 = "A"; std::string str2 = "B"; std::string str3 = "C"; std::string str4 = "D"; std::string str5 = "E"; HANDLE hThread1 = CreateThread(NULL, 0, Fun, (void*)str1.c_str(), 0, NULL); HANDLE hThread2 = CreateThread(NULL, 0, Fun, (void*)str2.c_str(), 0, NULL); HANDLE hThread3 = CreateThread(NULL, 0, Fun, (void*)str3.c_str(), 0, NULL); HANDLE hThread4 = CreateThread(NULL, 0, Fun, (void*)str4.c_str(), 0, NULL); HANDLE hThread5 = CreateThread(NULL, 0, Fun, (void*)str5.c_str(), 0, NULL); //关闭线程 CloseHandle(hThread1); CloseHandle(hThread2); CloseHandle(hThread3); CloseHandle(hThread4); CloseHandle(hThread5); getchar(); DeleteCriticalSection(&cs); return 0; }
测试效果
3、Linux平台
在Linux环境下,没有Windows下的临界区的概念,但是也可以利用互斥量实现该功能。
#include <pthread.h> int pthread_mutexattr_init(pthread_mutexattr_t *attr); /*初始化函数*/ int pthread_mutexattr_destroy(pthread_mutexattr_t *attr);/*去初始化函数*/ int pthread_mutex_lock(pthread_mutexattr_t *attr)/*加锁*/ int pthread_mutex_unlock(pthread_mutexattr_t *attr)/*解锁*/
临界区与互斥体的区别:
- 临界区只能用于对象在同一进程里线程间的互斥访问;互斥体可以用于对象进程间或线程间的互斥访问。
- 临界区是非内核对象,只在用户态进行锁操作,速度快;互斥体是内核对象,在核心态进行锁操作,速度慢。
- 临界区和互斥体在Windows平台都下可用;Linux下只有互斥体可用。
- 临界区:通过对多线程的串行化来访问公共资源或一段代码,速度快,适合控制数据访问。
- 互斥量:为协调共同对一个共享资源的单独访问而设计的。