1.CRITICAL_SECTION:不能锁定资源,只是同步代码简单说,当一个线程执行了EnterCritialSection之后,cs里面的信息便被修改了,以指明哪一个线程占用了它。而此时,并没有任何资源被“锁定”。只不过,在这个线程尚未执行LeaveCriticalSection之前,其它线程碰到EnterCritialSection语句的话,就会处于等待状态,相当于线程被挂起了。 这种情况下,就起到了保护共享资源的作用。 CRITICAL_SECTION临界区的使用在线程同步中应该算是比较简单,在使用临界区的时候要注意,每一个共享资源就有一个CRITICAL_SECTION,如果要一次访问多个共享变量,各个线程要保证访问的顺序一致,如果不一致,很可能发生死锁。 1: InitializeCriticalSection(&g_cs_listview); 2: InitializeCriticalSectionAndSpinCount(&g_cs_listview); 3: DeleteCriticalSection(&g_cs_listview); 4: TryEnterCriticalSection(&g_cs_listview); 5: EnterCriticalSection(&g_cs_listview); 6: LeaveCriticalSection(&g_cs_listview); 注意:假如多个线程都在等待同一个critical section,究竟哪个线程会先获得它的所有权是不一定的,cirtical section在这方面没有保证.
2.Semaphore信号量:Semaphore对象用来控制对资源的并发访问数。内部有个计数器,当值>=0设置了信号,==0清除信号。每次调用wait函数计数器都减1。调用ReleaseSemaphore时将计数器设置为lREleaseCount的指定的值。 // 创建信号量,且设置为1表示每次只能有一个线程访问; // 释放本进程的信号量 // 等待一个对象是否可用; 1: #include "stdafx.h" 2: #include <windows.h> 3: #include <iostream> 4: using namespace std; 5: 6: const int MAX_RUNNUM = 3; //最多运行实例个数 7: void PrintInfo() 8: { 9: char c; 10: cout << "run program" << endl; 11: cout << "input s to exit program!" << endl; 12: while (1) 13: { 14: cin >> c; 15: if (c == 's') 16: { 17: break; 18: } 19: Sleep(10); 20: } 21: } 22: int main(int argc, char* argv[]) 23: { 24: HANDLE hSe = CreateSemaphore(NULL, MAX_RUNNUM, MAX_RUNNUM, "semaphore_test"); 25: DWORD ret = 0; 26: if (hSe == NULL) 27: { 28: cout << "createsemaphore failed with code: " << GetLastError() << endl; 29: return -1; 30: } 31: ret = WaitForSingleObject(hSe, 1000); 32: if (ret == WAIT_TIMEOUT) 33: { 34: cout << "you have runned " << MAX_RUNNUM << " program!" << endl; 35: ret = WaitForSingleObject(hSe, INFINITE); 36: } 37: PrintInfo(); 38: ReleaseSemaphore(hSe, 1, NULL); 39: CloseHandle(hSe); 40: return 0; 41: }
3.Mutex-互斥体mutex互斥体的意思,当一个线程持有一个Mutex时,其它线程申请持有同一个Mutex会被阻塞在一个队列中,当互斥体释放后队列中的第一个线程首先获得使用权。 //创建一个互斥体 //销毁互斥体 // 等待一个对象是否可用; 1: //互斥体通常用于多进程之间的同步问题 2: 3: //程序运行单个实例: 4: #include "stdafx.h" 5: #include <windows.h> 6: #include <process.h> 7: #include <iostream> 8: using namespace std; 9: 10: //当输入s或者c时候结束程序 11: void PrintInfo(HANDLE& h, char t) 12: { 13: char c; 14: while (1) 15: { 16: cin >> c; 17: if (c == t) 18: { 19: ReleaseMutex(h); 20: CloseHandle(h); 21: break; 22: } 23: Sleep(100); 24: } 25: } 26: int main(int argc, char* argv[]) 27: { 28: //创建mutex,当已经程序发现已经有这个mutex时候,就相当于openmutex 29: HANDLE hHandle = CreateMutex(NULL, FALSE, "mutex_test"); 30: if (GetLastError() == ERROR_ALREADY_EXISTS) 31: { 32: cout << "you had run this program!" << endl; 33: cout << "input c to close this window" << endl; 34: PrintInfo(hHandle, 'c'); 35: return 1; 36: } 37: cout << "program run!" << endl; 38: cout << "input s to exit program" <<endl; 39: PrintInfo(hHandle, 's'); 40: return 1; 41: }
4.Event事件创建一个事件: 释放一个事件: 设置一个事件有信号: 复位一个Event对象
等待一个或多个事件有信号: WaitForMultipleObjects(nCount, handle_array, false, INFINITE/*等待时间*/); wait…返回值: 1: /*简单示例,一个线程不停读取用户输入并放入message列表, 2: 另一个线程模拟将message发送出去,如果没有消息,则发送线程处于阻塞状态等待, 3: 一旦有消息录入,输入线程将event置位,发送线程即被激活并逐个发送消息。*/ 4: #include "stdafx.h" 5: #include <windows.h> 6: #include <tchar.h> 7: #include <iostream> 8: #include <list> 9: #include <string> 10: using namespace std; 11: 12: #ifdef _UNICODE 13: typedef wstring tstring; 14: #define tcout wcout 15: #define tcin wcin 16: #else 17: typedef string tstring; 18: #define tcout cout 19: #define tcin cin 20: #endif /* _UNICODE */ 21: 22: typedef list<tstring> StringList; 23: 24: HANDLE hMutex = NULL; 25: HANDLE hEvent = NULL; 26: HANDLE hSendThread = NULL; 27: StringList messages; 28: 29: bool isRunning; 30: 31: DWORD WINAPI SendThreadProc(LPVOID lpThreadParameter) 32: { 33: DWORD dw; 34: while(isRunning) 35: { 36: dw = WaitForSingleObject(hEvent, INFINITE); 37: if(dw != WAIT_OBJECT_0) 38: { 39: tcout << _T("Wait error.") << endl; 40: return -1; 41: } 42: dw = WaitForSingleObject(hMutex, INFINITE); 43: if(WAIT_OBJECT_0 != dw && WAIT_ABANDONED != dw) 44: { 45: tcout << _T("Wait error.") << endl; 46: return -2; 47: } 48: 49: StringList list(messages); 50: messages.clear(); 51: 52: ReleaseMutex(hMutex); 53: 54: for(StringList::iterator i = list.begin(); i != list.end(); i++) 55: { 56: Sleep(1000); //休眠1秒模拟发送所耗时间 57: 58: tcout << _T("/* Send Message:") << *i << _T(" */"); 59: } 60: 61: } 62: 63: return 0; 64: } 65: 66: int _tmain(int argc, _TCHAR* argv[]) 67: { 68: hMutex = CreateMutex(NULL, FALSE, NULL); 69: hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); 70: isRunning = true; 71: 72: hSendThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)SendThreadProc, NULL, 0, NULL); 73: 74: while(isRunning) 75: { 76: tstring s; 77: tcin >> s; 78: if(s == _T("quit")) 79: { 80: isRunning = true; 81: break; 82: } 83: 84: DWORD dw = WaitForSingleObject(hMutex, INFINITE); 85: if(WAIT_OBJECT_0 != dw && WAIT_ABANDONED != dw) 86: { 87: tcout << _T("Wait error.") << endl; 88: return -1; 89: } 90: messages.push_back(s); 91: ReleaseMutex(hMutex); 92: SetEvent(hEvent); 93: } 94: 95: CloseHandle(hMutex); 96: CloseHandle(hEvent); 97: CloseHandle(hSendThread); 98: 99: return 0; 100: } |
|
来自: 张岩峰 > 《C plus plus》