MFC 线程同步 —— CSemaphore类使用

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();
	

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值