事件对象(CreateEvent)、互斥对象(CreateMutex)、关键代码段(InitializeCriticalSection)都是保证数据安全的一些措施。
1、互斥对象和事件对象属于内核对象,利用内核对象进行线程同步,速度较慢,但可以实现在多个进程中各线程间进行同步。
2、关键代码段式工作在用户方式下,同步速度较快,但在使用关键代码段时,很容易进入死锁状态,因为在进入关键代码时无法设定超时值。
MFC下InitializeCriticalSection()和DeleteCriticalSection()可以放在类的构造函数和析构函数中
CreateEvent
代码实例1.1 Event
- #include "stdafx.h"
- #include <iostream>
- #include <windows.h>
- using namespace std;
- DWORD WINAPI thread1fun(LPVOID);
- DWORD WINAPI thread2fun(LPVOID);
- int tickets=20;
- HANDLE hEvent;
- int main()
- {
- HANDLE hthread1,hthread2;
- ////the third parameter: 指定事件对象的初始状态。
- /// 如果为TRUE,初始状态为有信号状态; FALSE:为无信号状态。
- /// the second parameter: TRUE:人工重置,否则自动重置无信号状态
- hEvent=CreateEvent(NULL,FALSE,FALSE,_T("tickets"));
- if(hEvent)
- {
- if(ERROR_ALREADY_EXISTS==GetLastError()) //当前有实例在
- {
- cout<<"only instance can run\n";
- }
- }
- SetEvent(hEvent); ///set 有信号状态
- hthread1=CreateThread(NULL,0,thread1fun,NULL,0,NULL);
- // Sleep(11);
- hthread2=CreateThread(NULL,0,thread2fun,NULL,0,NULL);
- // while(1)
- Sleep(10000);
- CloseHandle(hthread1);//关闭句柄并不终止程序
- CloseHandle(hthread2);
- CloseHandle(hEvent);
- return 0;
- }
- DWORD WINAPI thread1fun(LPVOID lpParameter)
- {
- while(1)
- { ///请求到信号,系统自动重置为无信号状态
- WaitForSingleObject(hEvent,INFINITE);
- if(tickets>0)
- {
- cout<<"thread 1: "<<tickets--<<endl;
- Sleep(50);
- }
- else
- break;
- SetEvent(hEvent); //set 有信号状态
- }
- return 0;
- }
- DWORD WINAPI thread2fun(LPVOID lpParameter)
- {
- while(1)
- {
- WaitForSingleObject(hEvent,INFINITE); /////请求到信号,系统重置为无信号状态
- if(tickets>0)
- {
- cout<<"thread 2: "<<tickets--<<endl;
- Sleep(10);
- }
- else
- break;
- SetEvent(hEvent); ////set 有信号状态
- }
- return 0;
- }
执行结果:
代码实例1.2 无 Event
- #include "stdafx.h"
- #include <iostream>
- #include <windows.h>
- using namespace std;
- DWORD WINAPI thread1fun(LPVOID);
- DWORD WINAPI thread2fun(LPVOID);
- int tickets=20;
- HANDLE hEvent;
- int main()
- {
- HANDLE hthread1,hthread2;
- ////the third parameter: 指定事件对象的初始状态。
- /// 如果为TRUE,初始状态为有信号状态; FALSE:为无信号状态。
- /// the second parameter: TRUE:人工重置,否则自动重置无信号状态
- //hEvent=CreateEvent(NULL,FALSE,FALSE,_T("tickets"));
- //if(hEvent)
- {
- if(ERROR_ALREADY_EXISTS==GetLastError()) //当前有实例在
- {
- cout<<"only instance can run\n";
- }
- }
- //SetEvent(hEvent); ///set 有信号状态
- hthread1=CreateThread(NULL,0,thread1fun,NULL,0,NULL);
- // Sleep(11);
- hthread2=CreateThread(NULL,0,thread2fun,NULL,0,NULL);
- // while(1)
- Sleep(10000);
- CloseHandle(hthread1);
- CloseHandle(hthread2);
- CloseHandle(hEvent);
- return 0;
- }
- DWORD WINAPI thread1fun(LPVOID lpParameter)
- {
- while(1)
- { ///请求到信号,系统自动重置为无信号状态
- //WaitForSingleObject(hEvent,INFINITE);
- if(tickets>0)
- {
- cout<<"thread 1: "<<tickets--<<endl;
- Sleep(30);
- }
- else
- break;
- //SetEvent(hEvent); //set 有信号状态
- }
- return 0;
- }
- DWORD WINAPI thread2fun(LPVOID lpParameter)
- {
- while(1)
- {
- //WaitForSingleObject(hEvent,INFINITE); /////请求到信号,系统重置为无信号状态
- if(tickets>0)
- {
- cout<<"thread 2: "<<tickets--<<endl;
- Sleep(10);
- }
- else
- break;
- //SetEvent(hEvent); ////set 有信号状态
- }
- return 0;
- }
代码实例 2.1 有 Mutex
- #include "StdAfx.h"
- #include <iostream>
- #include <windows.h>
- using namespace std;
- DWORD WINAPI thread1fun(LPVOID);
- DWORD WINAPI thread2fun(LPVOID);
- int tickets=20;
- HANDLE hMutex;
- int main()
- {
- HANDLE hthread1,hthread2;
- hMutex=CreateMutex(NULL,FALSE,_T("tickets")); ///TRUE :main thread got mutex object
- hthread1=CreateThread(NULL,0,thread1fun,NULL,0,NULL);
- hthread2=CreateThread(NULL,0,thread2fun,NULL,0,NULL);
- CloseHandle(hthread1);
- CloseHandle(hthread2);
- if(hMutex)
- {
- if(ERROR_ALREADY_EXISTS==GetLastError())
- {
- cout<<"only instance can run!"<<endl;
- return 0;
- }
- }
- Sleep(10000);
- return 0;
- }
- DWORD WINAPI thread1fun(LPVOID lpParameter)
- {
- while(1)
- {
- WaitForSingleObject(hMutex,INFINITE);
- if(tickets>0)
- {
- Sleep(30);
- cout<<"thread 1: "<<tickets--<<endl;
- }
- else
- break;
- ReleaseMutex(hMutex); //释放当前线程ID,互斥对象计数器-1
- } //谁拥有互斥对象,你可以释放
- return 0;
- }
- DWORD WINAPI thread2fun(LPVOID lpParameter)
- {
- while(1)
- {
- WaitForSingleObject(hMutex,INFINITE);
- if(tickets>0)
- {
- Sleep(10);
- cout<<"thread 2: "<<tickets--<<endl;
- }
- else
- break;
- ReleaseMutex(hMutex);
- }
- return 0;
- }
执行结果 :
代码实例 2.2 无Mutex
- #include "StdAfx.h"
- #include <iostream>
- #include <windows.h>
- using namespace std;
- DWORD WINAPI thread1fun(LPVOID);
- DWORD WINAPI thread2fun(LPVOID);
- int tickets=20;
- HANDLE hMutex;
- int main()
- {
- HANDLE hthread1,hthread2;
- //hMutex=CreateMutex(NULL,FALSE,_T("tickets")); ///TRUE :main thread got mutex object
- hthread1=CreateThread(NULL,0,thread1fun,NULL,0,NULL);
- hthread2=CreateThread(NULL,0,thread2fun,NULL,0,NULL);
- CloseHandle(hthread1);
- CloseHandle(hthread2);
- //if(hMutex)
- {
- if(ERROR_ALREADY_EXISTS==GetLastError())
- {
- cout<<"only instance can run!"<<endl;
- return 0;
- }
- }
- Sleep(10000);
- return 0;
- }
- DWORD WINAPI thread1fun(LPVOID lpParameter)
- {
- while(1)
- {
- //WaitForSingleObject(hMutex,INFINITE);
- if(tickets>0)
- {
- Sleep(30);
- cout<<"thread 1: "<<tickets--<<endl;
- }
- else
- break;
- //ReleaseMutex(hMutex); //释放当前线程ID,互斥对象计数器-1
- } //谁拥有互斥对象,你可以释放
- return 0;
- }
- DWORD WINAPI thread2fun(LPVOID lpParameter)
- {
- while(1)
- {
- //WaitForSingleObject(hMutex,INFINITE);
- if(tickets>0)
- {
- Sleep(10);
- cout<<"thread 2: "<<tickets--<<endl;
- }
- else
- break;
- //ReleaseMutex(hMutex);
- }
- return 0;
- }
关键代码段3.1:
- #include "StdAfx.h"
- #include <iostream>
- #include <windows.h>
- using namespace std;
- DWORD WINAPI thread1fun(LPVOID);
- DWORD WINAPI thread2fun(LPVOID);
- int tickets=20;
- CRITICAL_SECTION g_cs; /*---
- 每个线程中访问临界资源的那段程序称为临界区(Critical Section)
- (临界资源是一次仅允许一个线程使用的共享资源)。
- 每次只准许一个线程进入临界区,进入后不允许其他线程进入。
- 不论是硬件临界资源,还是软件临界资源,多个线程必须互斥地对它进行访问.
- ------------------**/
- int main()
- {
- HANDLE hthread1,hthread2;
- InitializeCriticalSection(&g_cs);
- hthread1=CreateThread(NULL,0,thread1fun,NULL,0,NULL);
- // Sleep(11);
- hthread2=CreateThread(NULL,0,thread2fun,NULL,0,NULL);
- CloseHandle(hthread1);
- CloseHandle(hthread2);
- // while(1)
- Sleep(4000);
- DeleteCriticalSection(&g_cs);
- return 0;
- }
- DWORD WINAPI thread1fun(LPVOID lpParameter)
- {
- while(1)
- {
- EnterCriticalSection(&g_cs); //进入关键代码段
- if(tickets>0)
- {
- Sleep(10);
- cout<<"thread 1: "<<tickets--<<endl;
- }
- else
- break;
- LeaveCriticalSection(&g_cs);//释放临界区对象所有权
- Sleep(5);
- }
- return 0;
- }
- DWORD WINAPI thread2fun(LPVOID lpParameter)
- {
- while(1)
- {
- EnterCriticalSection(&g_cs); /////请求到信号,系统重置为无信号状态
- if(tickets>0)
- {
- Sleep(10);
- cout<<"thread 2: "<<tickets--<<endl;
- }
- else
- break;
- LeaveCriticalSection(&g_cs);
- Sleep(15);
- }
- return 0;
- }
执行结果 :
代码实例:无代码段约束3.2
- #include "StdAfx.h"
- #include <iostream>
- #include <windows.h>
- using namespace std;
- DWORD WINAPI thread1fun(LPVOID);
- DWORD WINAPI thread2fun(LPVOID);
- int tickets=20;
- CRITICAL_SECTION g_cs; /*---
- 每个线程中访问临界资源的那段程序称为临界区(Critical Section)
- (临界资源是一次仅允许一个线程使用的共享资源)。
- 每次只准许一个线程进入临界区,进入后不允许其他线程进入。
- 不论是硬件临界资源,还是软件临界资源,多个线程必须互斥地对它进行访问.
- ------------------**/
- int main()
- {
- HANDLE hthread1,hthread2;
- //InitializeCriticalSection(&g_cs);
- hthread1=CreateThread(NULL,0,thread1fun,NULL,0,NULL);
- // Sleep(11);
- hthread2=CreateThread(NULL,0,thread2fun,NULL,0,NULL);
- CloseHandle(hthread1);
- CloseHandle(hthread2);
- // while(1)
- Sleep(4000);
- //DeleteCriticalSection(&g_cs);
- return 0;
- }
- DWORD WINAPI thread1fun(LPVOID lpParameter)
- {
- while(1)
- {
- //EnterCriticalSection(&g_cs); //进入关键代码段
- if(tickets>0)
- {
- Sleep(10);
- cout<<"thread 1: "<<tickets--<<endl;
- }
- else
- break;
- //LeaveCriticalSection(&g_cs);//释放临界区对象所有权
- Sleep(5);
- }
- return 0;
- }
- DWORD WINAPI thread2fun(LPVOID lpParameter)
- {
- while(1)
- {
- //EnterCriticalSection(&g_cs); /////请求到信号,系统重置为无信号状态
- if(tickets>0)
- {
- Sleep(10);
- cout<<"thread 2: "<<tickets--<<endl;
- }
- else
- break;
- //LeaveCriticalSection(&g_cs);
- Sleep(15);
- }
- return 0;
- }
转载于https://blog.csdn.net/makenothing/article/details/43269151