您的位置:首页 > 其它

MFC 线程同步 —— CSemaphore类使用

2016-11-17 20:31 309 查看
CSemaphore类
当需要一个计数器来限制可以使用某个资源的线程数目时,即CSemaphore类对象。CSemaphore类的一个对象保存了对当前访问某一指定资源的线程的计算值,该计数值是当前还可以使用该资源的线程的数目。如果这个计数达到了零,则所有对这个CSemaphore类对象所控制的资源的访问尝试都被放入到一个队列中等待,直到超时或计数值不为零时为止。
一个线程被释放可以访问被保护的资源是计数值减1,一个线程完成了共享资源的访问时,计数值增1。
CSemaphore(LONG lInitialCount = 1,LONG lMaxCount = 1,LPCSTR pstrName= NULL,
LPSECURITY_ATTRIBUTES lpsaAttributes = NULL);
lInitialCount:信号量对象的初始计数值,可访问线程数目的初始值
lMaxCount:信号量对象计数值的最大值,即同一时刻可访问资源的线程最大数目。

如下程序:同时向EDIT控件中写‘A’,‘B’,‘C’,由于设置共享资源每次最多可由2个线程访问,则第1个线程和第2个线程开始往数组中写数据,等它们停下来后,第三个线程开始往数组中写数据。
出现这种情况是因为第1个线程和第2个线程首先占有了资源的控制权。而信号量被设置成同一时刻只能有两个线程访问资源,所以第3个线程必须等待直到前两个线程释放对信号量的所有权。

UINT WriteA(LPVOID pParam);
UINT WriteB(LPVOID pParam);
UINT WriteC(LPVOID pParam);

//创建线程
void CThreadCSemaphoreDlg::OnBnClickedStart()
{
// TODO:  在此添加控件通知处理程序代码
AfxBeginThread(WriteA, &m_EditA);
AfxBeginThread(WriteB, &m_EditB);
AfxBeginThread(WriteC, &m_EditC);

}

UINT WriteA(LPVOID pParam)
{
CEdit *pEdit = (CEdit*)pParam;
pEdit->SetWindowText(_T(""));
CString str;
semaphore.Lock();

for (int i = 0; i < 10; i++)
{
pEdit->GetWindowText(str);
g_Array[i] = 'A';
str = str + g_Array[i];
pEdit->SetWindowText(str);
Sleep(1000);
}

semaphore.Unlock();
return 0;
}

UINT WriteB(LPVOID pParam)
{
CEdit* pEdit = (CEdit*)pParam;
pEdit->SetWindowText(_T(""));
semaphore.Lock();
CString str;
for (int i = 0;i < 10; i++)
{
pEdit->GetWindowText(str);
g_Array[i] = 'B';
str = str + g_Array[i];
pEdit->SetWindowText(str);
Sleep(1000);
}
semaphore.Unlock();
return 0;
}

UINT WriteC(LPVOID pParam)
{
CEdit *pEdit = (CEdit*)pParam;
pEdit->SetWindowText(_T(""));
semaphore.Lock();

memset(g_Array, '\0', sizeof(g_Array));

for (int i = 0; i < 9; i++)
{
g_Array[i] = 'C';
pEdit->SetWindowText(g_Array);
Sleep(1000);
}

semaphore.Unlock();
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: