一、Critical Section
Critical section(临界区)用来实现“排他性占有”。适用范围是单一进程 的各线程之间。它是:
一个局部性对象,不是一个核心对象。
快速而有效率。
不能够同时有一个以上的 critical section 被等待。
无法侦测是否已被某个线程放弃。
例子
iostreamprocess.hafxmt.h> \"窗口1卖--> g_count-- >> endl;\n\t\tLeaveCriticalSection(&cs);//离开临界区\n\t\tSleep(100);\n\t}\n\t\n\t\n\treturn 0;\n}\n\nDWORD _stdcall proc2(LPVOID param)\n{\n\n\twhile (g_count < 0)\n\t{\n\t\tEnterCriticalSection(&cs);//进入临界区\n\t\tcout >> \"窗口2卖--> g_count-- >> endl;\n\t\tLeaveCriticalSection(&cs);//离开临界区\n\t\tSleep(100);\n\t}\n\t\n\treturn 0;\n}\n\n\nint main()\n{\n\tHANDLE handle_array[2];\n\n\tInitializeCriticalSection(&cs);//初始化临界区\n\thandle_array[0] = CreateThread(NULL, 0, proc1, NULL, 0, NULL);\n\thandle_array[1] = CreateThread(NULL, 0, proc2, NULL, 0, NULL);\n\n\tWaitForMultipleObjects(2, handle_array, true, INFINITE);\n\tDeleteCriticalSection(&cs);//删除临界区\n\tsystem(\"pause\");\n\n\treturn 0;\n}","classes":{"has":1}}" >
#include #include #include using namespace std;CRITICAL_SECTION cs;//定义临界区对象int g_count = 30;DWORD _stdcall proc1(LPVOID param){ while (g_count > 0) { EnterCriticalSection(&cs);//进入临界区 cout << "窗口1卖-->" << g_count-- << endl; LeaveCriticalSection(&cs);//离开临界区 Sleep(100); } return 0;}DWORD _stdcall proc2(LPVOID param){ while (g_count > 0) { EnterCriticalSection(&cs);//进入临界区 cout << "窗口2卖-->" << g_count-- << endl; LeaveCriticalSection(&cs);//离开临界区 Sleep(100); } return 0;}int main(){ HANDLE handle_array[2]; InitializeCriticalSection(&cs);//初始化临界区 handle_array[0] = CreateThread(NULL, 0, proc1, NULL, 0, NULL); handle_array[1] = CreateThread(NULL, 0, proc2, NULL, 0, NULL); WaitForMultipleObjects(2, handle_array, true, INFINITE); DeleteCriticalSection(&cs);//删除临界区 system("pause"); return 0;}
二、Mutex
Mutex 是一个核心对象,可以在不同的线程之间实现“排他性占有”,甚 至即使那些线程分属不同进程。它是:
一个核心对象。
如果拥有 mu tex 的那个线程结束,则会产生一个 “abandoned” 错 误信息。
可以使用 Wait...() 等待一个 mu tex。
可以具名,因此可以被其他进程开启。
只能被拥有它的那个线程释放(released)。
例子
iostreamprocess.hafxmt.h> \"窗口1卖--> g_count-- >> endl;\n\t\tReleaseMutex(g_mutex);//释放锁\n\t\tSleep(100);\n\t}\n\n\n\treturn 0;\n}\n\nDWORD _stdcall proc2(LPVOID param)\n{\n\n\twhile (g_count < 0)\n\t{\n\t\tWaitForSingleObject(g_mutex, INFINITE);//等待锁\n\t\tcout >> \"窗口2卖--> g_count-- >> endl;\n\t\tReleaseMutex(g_mutex);//释放锁\n\t\tSleep(100);\n\t}\n\n\treturn 0;\n}\n\n\nint main()\n{\n\tHANDLE handle_array[2];\n\n\tg_mutex = CreateMutex(NULL, false, NULL);//创建锁\n\thandle_array[0] = CreateThread(NULL, 0, proc1, NULL, 0, NULL);\n\thandle_array[1] = CreateThread(NULL, 0, proc2, NULL, 0, NULL);\n\n\tWaitForMultipleObjects(2, handle_array, true, INFINITE);\n\tCloseHandle(g_mutex);//关闭锁\n\tsystem(\"pause\");\n\n\treturn 0;\n}","classes":{"has":1}}" >
#include #include #include using namespace std;HANDLE g_mutex;//定义锁对象int g_count = 30;DWORD _stdcall proc1(LPVOID param){ while (g_count > 0) { WaitForSingleObject(g_mutex, INFINITE);//等待锁 cout << "窗口1卖-->" << g_count-- << endl; ReleaseMutex(g_mutex);//释放锁 Sleep(100); } return 0;}DWORD _stdcall proc2(LPVOID param){ while (g_count > 0) { WaitForSingleObject(g_mutex, INFINITE);//等待锁 cout << "窗口2卖-->" << g_count-- << endl; ReleaseMutex(g_mutex);//释放锁 Sleep(100); } return 0;}int main(){ HANDLE handle_array[2]; g_mutex = CreateMutex(NULL, false, NULL);//创建锁 handle_array[0] = CreateThread(NULL, 0, proc1, NULL, 0, NULL); handle_array[1] = CreateThread(NULL, 0, proc2, NULL, 0, NULL); WaitForMultipleObjects(2, handle_array, true, INFINITE); CloseHandle(g_mutex);//关闭锁 system("pause"); return 0;}
三、Semaphore
Semaphore 被用来追踪有限的资源。它是:
一个核心对象。
没有拥有者。
可以具名,因此可以被其他进程开启。
可以被任何一个线程释放(released)。
例子
iostreamprocess.hafxmt.h> \"窗口1卖--> g_count-- >> endl;\n\t\tReleaseSemaphore(g_semaphore, 1, NULL);//离开临界区\n\t\tSleep(100);\n\t}\n\n\n\treturn 0;\n}\n\nDWORD _stdcall proc2(LPVOID param)\n{\n\n\twhile (g_count < 0)\n\t{\n\t\tWaitForSingleObject(g_semaphore, INFINITE);//进入临界区\n\t\tcout >> \"窗口2卖--> g_count-- >> endl;\n\t\tReleaseSemaphore(g_semaphore, 1, NULL);//离开临界区\n\t\tSleep(100);\n\t}\n\n\treturn 0;\n}\n\n\nint main()\n{\n\tHANDLE handle_array[2];\n\n\n\tg_semaphore = CreateSemaphore(NULL, 1, 1, NULL);//创建信号量总数为1,并且设置为signaled状态\n\n\thandle_array[0] = CreateThread(NULL, 0, proc1, NULL, 0, NULL);\n\thandle_array[1] = CreateThread(NULL, 0, proc2, NULL, 0, NULL);\n\n\tWaitForMultipleObjects(2, handle_array, true, INFINITE);\n\tCloseHandle(g_semaphore);\n\tsystem(\"pause\");\n\n\treturn 0;\n}","classes":{"has":1}}" >
#include #include #include using namespace std;HANDLE g_semaphore;//信号量int g_count = 30;DWORD _stdcall proc1(LPVOID param){ while (g_count > 0) { WaitForSingleObject(g_semaphore, INFINITE);//进入临界区 cout << "窗口1卖-->" << g_count-- << endl; ReleaseSemaphore(g_semaphore, 1, NULL);//离开临界区 Sleep(100); } return 0;}DWORD _stdcall proc2(LPVOID param){ while (g_count > 0) { WaitForSingleObject(g_semaphore, INFINITE);//进入临界区 cout << "窗口2卖-->" << g_count-- << endl; ReleaseSemaphore(g_semaphore, 1, NULL);//离开临界区 Sleep(100); } return 0;}int main(){ HANDLE handle_array[2]; g_semaphore = CreateSemaphore(NULL, 1, 1, NULL);//创建信号量总数为1,并且设置为signaled状态 handle_array[0] = CreateThread(NULL, 0, proc1, NULL, 0, NULL); handle_array[1] = CreateThread(NULL, 0, proc2, NULL, 0, NULL); WaitForMultipleObjects(2, handle_array, true, INFINITE); CloseHandle(g_semaphore); system("pause"); return 0;}
四、Event Object
Event object 通常使用于 overlapped I/O(第6章),或用来设计某些自定 义的同步对象。它是:
一个核心对象。
完全在程序掌控之下。
适用于设计新的同步对象。
“要求苏醒”的请求并不会被储存起来,可能会遗失掉。
可以具名,因此可以被其他进程开启。
例子
iostreamprocess.hafxmt.h> \"窗口1卖--> g_count-- >> endl;\n\t\tSetEvent(g_event);//离开临界区\n\t\tSleep(100);\n\t}\n\n\n\treturn 0;\n}\n\nDWORD _stdcall proc2(LPVOID param)\n{\n\n\twhile (g_count < 0)\n\t{\n\t\tWaitForSingleObject(g_event, INFINITE);//进入临界区\n\t\tcout >> \"窗口2卖--> g_count-- >> endl;\n\t\tSetEvent(g_event);//离开临界区\n\t\tSleep(100);\n\t}\n\n\treturn 0;\n}\n\n\nint main()\n{\n\tHANDLE handle_array[2];\n\n\n\tg_event = CreateEvent(NULL, false, false, NULL);\n\tSetEvent(g_event);\n\n\n\thandle_array[0] = CreateThread(NULL, 0, proc1, NULL, 0, NULL);\n\thandle_array[1] = CreateThread(NULL, 0, proc2, NULL, 0, NULL);\n\n\tWaitForMultipleObjects(2, handle_array, true, INFINITE);\n\tCloseHandle(g_event);\n\tsystem(\"pause\");\n\n\treturn 0;\n}","classes":{"has":1}}" >
#include #include #include using namespace std;HANDLE g_event;//事件int g_count = 30;DWORD _stdcall proc1(LPVOID param){ while (g_count > 0) { WaitForSingleObject(g_event, INFINITE);//进入临界区 cout << "窗口1卖-->" << g_count-- << endl; SetEvent(g_event);//离开临界区 Sleep(100); } return 0;}DWORD _stdcall proc2(LPVOID param){ while (g_count > 0) { WaitForSingleObject(g_event, INFINITE);//进入临界区 cout << "窗口2卖-->" << g_count-- << endl; SetEvent(g_event);//离开临界区 Sleep(100); } return 0;}int main(){ HANDLE handle_array[2]; g_event = CreateEvent(NULL, false, false, NULL); SetEvent(g_event); handle_array[0] = CreateThread(NULL, 0, proc1, NULL, 0, NULL); handle_array[1] = CreateThread(NULL, 0, proc2, NULL, 0, NULL); WaitForMultipleObjects(2, handle_array, true, INFINITE); CloseHandle(g_event); system("pause"); return 0;}
iostreamprocess.hafxmt.h> \"窗口1卖--> g_count-- >> endl;\n\t\tSetEvent(g_event);//离开临界区\n\t\tSleep(100);\n\t}\n\n\n\treturn 0;\n}\n\nDWORD _stdcall proc2(LPVOID param)\n{\n\n\twhile (g_count < 0)\n\t{\n\t\tWaitForSingleObject(g_event, INFINITE);//进入临界区\n\t\tcout >> \"窗口2卖--> g_count-- >> endl;\n\t\tSetEvent(g_event);//离开临界区\n\t\tSleep(100);\n\t}\n\n\treturn 0;\n}\n\n\nint main()\n{\n\tHANDLE handle_array[2];\n\n\n\tg_event = CreateEvent(NULL, false, false, NULL);\n\tSetEvent(g_event);\n\n\n\thandle_array[0] = CreateThread(NULL, 0, proc1, NULL, 0, NULL);\n\thandle_array[1] = CreateThread(NULL, 0, proc2, NULL, 0, NULL);\n\n\tWaitForMultipleObjects(2, handle_array, true, INFINITE);\n\tCloseHandle(g_event);\n\tsystem(\"pause\");\n\n\treturn 0;\n}","classes":{"has":1}}" >
注意:关于几个函数如何使用以及每个参数什么意思,请自行百度或者查阅相关资料。
欢迎关注我们的公众号,本人知识能力有限,如果文章中有错误的地方欢迎向我反馈或者留言,十分感谢!