| 物件 | 用途 | 初始值/最大值 |
CSemaphore m_semEmpty | 空槽位計數 | 初始 = 緩衝區大小,最大 = 緩衝區大小 |
CSemaphore m_semFull | 資料項計數 | 初始 = 0,最大 = 緩衝區大小 |
CMutex m_mutex | 保護緩衝區存取 | — |
完整實作程式碼
1. 對話方塊類別成員變數
class CProdConsDlg : public CDialog
{
bool m_bSlowDisplay; // 是否緩慢顯示
CWinThread* m_pProducerThread; // 生產者執行緒
CWinThread* m_pConsumerThread; // 消費者執行緒
CSemaphore* m_pSemEmpty; // 空信號
CSemaphore* m_pSemFull; // 滿信號
CMutex* m_pMutex; // 互斥鎖
CString m_strProducerBuf; // 生產資料顯示
CString m_strConsumerBuf; // 消費資料顯示
// ...
};
2. 生產者執行緒類別
class CProducerThread : public CWinThread
{
CProdConsDlg* m_pDlg;
public:
CProducerThread(CProdConsDlg* pDlg) : m_pDlg(pDlg) {}
virtual int Run()
{
CSingleLock lock(m_pDlg->m_pMutex);
for (int i = 0; i < MAX_DATA_COUNT; i++)
{
m_pDlg->m_pSemEmpty->Lock(); // 等待空槽
lock.Lock();
m_pDlg->m_strProducerBuf.Format(_T("%0.10d"), i);
lock.Unlock();
m_pDlg->m_pSemFull->Unlock(); // 通知有資料
if (m_pDlg->m_bSlowDisplay) Sleep(50);
}
return CWinThread::Run();
}
};
3. 消費者執行緒類別
class CConsumerThread : public CWinThread
{
CProdConsDlg* m_pDlg;
char m_data[CONSUMER_BUF_SIZE];
public:
CConsumerThread(CProdConsDlg* pDlg) : m_pDlg(pDlg) {}
virtual int Run()
{
char* pBuf = m_data;
for (int i = 0; i < MAX_DATA_COUNT; i += 10)
{
m_pDlg->m_pSemFull->Lock(); // 等待資料
m_pDlg->m_pMutex->Lock();
sprintf(pBuf, "%s", m_pDlg->m_strProducerBuf);
BOOL bSlow = m_pDlg->m_bSlowDisplay;
m_pDlg->m_pMutex->Unlock();
pBuf += 10;
if (pBuf >= m_data + CONSUMER_BUF_SIZE - 10) pBuf = m_data;
m_data[CONSUMER_BUF_SIZE] = 0;
m_pDlg->m_pMutex->Lock();
m_pDlg->m_strConsumerBuf = m_data;
m_pDlg->m_pMutex->Unlock();
if (bSlow) Sleep(100);
m_pDlg->m_pSemEmpty->Unlock(); // 釋放空槽
}
return CWinThread::Run();
}
};
4. 啟動執行緒(在對話方塊按鈕或 OnInitDialog 中)
m_pSemFull = new CSemaphore(0, 1); // 初始 0,最大 1
m_pSemEmpty = new CSemaphore(1, 1); // 初始 1,最大 1
m_pMutex = new CMutex();
m_pProducerThread = new CProducerThread(this);
m_pConsumerThread = new CConsumerThread(this);
m_strProducerBuf = _T("1234567890");
UpdateData(FALSE);
m_pProducerThread->CreateThread(CREATE_SUSPENDED);
m_pProducerThread->SetThreadPriority(THREAD_PRIORITY_IDLE);
m_pConsumerThread->CreateThread(CREATE_SUSPENDED);
m_pConsumerThread->SetThreadPriority(THREAD_PRIORITY_IDLE);
m_pProducerThread->ResumeThread();
m_pConsumerThread->ResumeThread();
關鍵點總結
- 兩個 Semaphore 分別追蹤「空槽」與「資料項」數量
- Mutex 保護實際緩衝區記憶體存取
- Lock/Unlock 配對確保同步正確性
- 執行緒優先權設為 IDLE 避免佔用過多 CPU
- 上一篇文章: VC++ 常用系統操作 20 例精選
- 下一篇文章: VC++ SDK 實作分割條控制項完整教學
Copyright ©
程式碼之家 All Rights Reserved