互斥量(互斥锁):在编程中,引入了对象互斥锁的概念,来保证共享数据操作的完整性。每个对象都对应于一个可称为" 互斥锁" 的标记,这个标记用来保证在任一时刻,只能有一个线程访问该对象。
互斥量:更安全和灵活
关键段:效率更高(因为关键段在用户模式下)
创建互斥量:m_hMutx = CreateMutex(0,0,0);
CreateMutex(LPSECURITY_ATTRIBUTES lpMutexAttributes,BOOL bInitialOwner,LPCTSTR lpName);
lpMutexAttributes:安全属性
bInitialOwner:初始拥有权
lpName:名字(跨进程使用)
等信号量:WaitForSingleObject(pthis->m_hMutx, INFINITE);
使用完之后释放信号量:ReleaseMutex(pthis->m_hMutx);
线程函数内代码如下,(其余代码请点击此链接,除构造函数里创建了互斥量外,其余代码均相同)
//线程函数
DWORD WINAPI CThreadGoodstwoDlg::ThreadProc(LPVOID lpParameter)
{
CThreadGoodstwoDlg *pthis = (CThreadGoodstwoDlg*)lpParameter;
//在循环里抢商品
CString str;
while (pthis->m_bFlagQuit)
{
if (pthis->m_nGoods < 0)
{
str.Format(L"%d退出了", GetCurrentThreadId());
//str.Format(_T("%d退出了", GetCurrentThreadId()));
pthis->m_lstBox.AddString(str);//将商品信息添加进列表控件
break;
}
Sleep(10);
/*EnterCriticalSection(&pthis->cs);*/
WaitForSingleObject(pthis->m_hMutx, INFINITE);
//INFINITE 相当于是直接阻塞
/*
if(WAIT_TIMEOUT == WaitForSingleObject(pthis->m_hMutx, 0)
continue; //相当于是异步
if(WAIT_TIMEOUT == WaitForSingleObject(pthis->m_hMutx, 100))
continue; //相当于是旋转锁+异步
*/
if (pthis->m_nGoods < 0)
{
str.Format(L"%d退出了", GetCurrentThreadId());
//str.Format(_T("%d退出了", GetCurrentThreadId()));
pthis->m_lstBox.AddString(str);//将商品信息添加进列表控件
//LeaveCriticalSection(&pthis->cs);
ReleaseMutex(pthis->m_hMutx);
break;
}
str.Format(L"%d正在抢商品%d",GetCurrentThreadId(), pthis->m_nGoods);
//InterlockedDecrement(&pthis->m_nGoods);
pthis->m_nGoods--;
//LeaveCriticalSection(&pthis->cs);
ReleaseMutex(pthis->m_hMutx);
pthis->m_lstBox.AddString(str);//将商品信息添加进列表控件
}
return 0;
}
---------------------------------------事件----------------------------------------
事件:当事件来时处理
CreateEvent(LPSECURITY_ATTRIBUTES lpEventAttributes,BOOL bManualReset, BOOL bInitialState,LPCTSTR lpName);
lpEventAttributes:安全属性
bManualReset:手动或者自动 1 手动 0 自动
bInitialState:有信号还是无信号 1 有信号 0 无信号
lpName:名字(跨进程)
创建事件:CreateEvent(0,0,1,0);//创建一个安全属性为零,自动的有信号事件,不跨进程
SetEvent();//将事件设置为有信号(自动事件使用)
ResetEvent ();//将事件设置为无信号(手动事件使用)
代码如下
//线程函数
DWORD WINAPI CThreadGoodstwoDlg::ThreadProc(LPVOID lpParameter)
{
CThreadGoodstwoDlg *pthis = (CThreadGoodstwoDlg*)lpParameter;
//在循环里抢商品
CString str;
while (pthis->m_bFlagQuit)
{
if (pthis->m_nGoods < 0)
{
str.Format(L"%d退出了", GetCurrentThreadId());
//str.Format(_T("%d退出了", GetCurrentThreadId()));
pthis->m_lstBox.AddString(str);//将商品信息添加进列表控件
break;
}
Sleep(10);
/*EnterCriticalSection(&pthis->cs);*/
WaitForSingleObject(pthis->m_hEvent, INFINITE);
if (pthis->m_nGoods < 0)
{
str.Format(L"%d退出了", GetCurrentThreadId());
//str.Format(_T("%d退出了", GetCurrentThreadId()));
pthis->m_lstBox.AddString(str);//将商品信息添加进列表控件
//LeaveCriticalSection(&pthis->cs);
SetEvent(pthis->m_hEvent);
break;
}
str.Format(L"%d正在抢商品%d",GetCurrentThreadId(), pthis->m_nGoods);
//InterlockedDecrement(&pthis->m_nGoods);
pthis->m_nGoods--;
//LeaveCriticalSection(&pthis->cs);
//ReleaseMutex(pthis->m_hMutx);
SetEvent(pthis->m_hEvent);
pthis->m_lstBox.AddString(str);//将商品信息添加进列表控件
}
return 0;
}
-----------------------------------信号量--------------------------------------
CreateSemaphore(LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,
LONG lInitialCount,LONG lMaximumCount, LPCTSTR lpName);
lpSemaphoreAttributes:安全属性
lInitialCount:初始化数量
lMaximumCount:最大数量
lpName:名字(跨进程)
创建信号量:m_hSemaphont = CreateSemaphore(0,1,10,0);
等信号量:WaitForSingleObject(pthis->m_hSemaphont, INFINITE);
用完之后释放信号量:ReleaseSemaphore(pthis->m_hSemaphont, 1, 0);
//线程函数
DWORD WINAPI CThreadGoodstwoDlg::ThreadProc(LPVOID lpParameter)
{
CThreadGoodstwoDlg *pthis = (CThreadGoodstwoDlg*)lpParameter;
//在循环里抢商品
CString str;
while (pthis->m_bFlagQuit)
{
if (pthis->m_nGoods < 0)
{
str.Format(L"%d退出了", GetCurrentThreadId());
//str.Format(_T("%d退出了", GetCurrentThreadId()));
pthis->m_lstBox.AddString(str);//将商品信息添加进列表控件
break;
}
Sleep(10);
/*EnterCriticalSection(&pthis->cs);*/
WaitForSingleObject(pthis->m_hSemaphont, INFINITE);
if (pthis->m_nGoods < 0)
{
str.Format(L"%d退出了", GetCurrentThreadId());
//str.Format(_T("%d退出了", GetCurrentThreadId()));
pthis->m_lstBox.AddString(str);//将商品信息添加进列表控件
//LeaveCriticalSection(&pthis->cs);
//SetEvent(pthis->m_hEvent);
ReleaseSemaphore(pthis->m_hSemaphont,1,0);
break;
}
str.Format(L"%d正在抢商品%d",GetCurrentThreadId(), pthis->m_nGoods);
//InterlockedDecrement(&pthis->m_nGoods);
pthis->m_nGoods--;
//LeaveCriticalSection(&pthis->cs);
//ReleaseMutex(pthis->m_hMutx);
//SetEvent(pthis->m_hEvent);
ReleaseSemaphore(pthis->m_hSemaphont, 1, 0);
pthis->m_lstBox.AddString(str);//将商品信息添加进列表控件
}
return 0;
}
注:所有的内核对象都有安全属性,基本都设置为0,都有名字,用来跨进程使用,如果名字为0,说明不跨进程。
如果感觉有帮助,请点个赞支持一下呗~