事件对象(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