I use a worker thread for some data processing in my MFC project. In the thread-controlling function, it needs to use some parameters (declared as member variables) to the data-processing. I use a sub-dialog (which is triggered by a menu item and contains a few edit controls) to change the values of the parameters, that the user inputs are first stored in a struct
, which is then used in the thread controlling function when needed. In order to prevent data-corruption, I also use Mutex to sync the worker thread and main thread, since both of them need to access the shared resource m_structBlkContSimPara
(the struct
that stores parameter values).
/*the following code is in my MFC Dlg Project head file*/
struct RecExtractParam {
bool bMod;
float fSimBlkShpWt;
float fSimGrPosWt;
float fSimGrTxtAttWt;
float fSimGrTypesWt;
float fDataUnitGroupSimThld;
float fVertDistThld;
RecExtractParam() {
bMod = false;
fSimBlkShpWt = 0;
fSimGrPosWt = 0;
fSimGrTxtAttWt = 0;
fSimGrTypesWt = 0;
fDataUnitGroupSimThld = 0;
fVertDistThld = 0;
}};
RecExtractParam m_structBlkContSimPara;
// parameters for some data processing
float m_fSimBlkShpWt;
float m_fSimGrPosWt;
float m_fSimGrTxtAttWt;
float m_fSimGrTypesWt;
float m_fDataUnitGroupSimThld;
float m_fVertDistThld;
CMutex m_Mutex;
afx_msg void OnToolsBlockContentSimilarityThreshold();
static UINT RecExtractThreadCtrlFunc(LPVOID pParam);
UINT DoThreadProc();
// button clicked handler for launching data processing
void CXMLDOMFromVCDlg::OnBnClickedDataRecExtractButton()
{
// TODO: Add your control notification handler code here
// some code for other processing
// start the thread for data record extraction
AfxBeginThread(RecExtractThreadCtrlFunc, this);
// some code for other processing
}
// menu item command handler for parameter inputs
void CXMLDOMFromVCDlg::OnToolsBlockContentSimilarityThreshold()
{
// TODO: Add your command handler code here
// CBlkContSimThldDlg is a sub-dialog for user input
CBlkContSimThldDlg dlgBlkContSimThld(this);
if (dlgBlkContSimThld.DoModal() == IDOK)
{
CSingleLock singleLock(&m_Mutex);
// try to capture the shared resource
singleLock.Lock();
m_structBlkContSimPara.bMod = true;
m_structBlkContSimPara.fDataUnitGroupSimThld = dlgBlkContSimThld.m_fDlgBlkContSimThld;
m_structBlkContSimPara.fSimBlkShpWt = dlgBlkContSimThld.m_fDlgGrShpWt;
m_structBlkContSimPara.fSimGrPosWt = dlgBlkContSimThld.m_fDlgGrPosWt;
m_structBlkContSimPara.fSimGrTxtAttWt = dlgBlkContSimThld.m_fDlgGrTxtAttWt;
m_structBlkContSimPara.fSimGrTypesWt = dlgBlkContSimThld.m_fDlgGrContTypeWt;
m_structBlkContSimPara.fVertDistThld = dlgBlkContSimThld.m_fDlgGrVertDistThld;
singleLock.Unlock();
}
}
// thread controlling function
UINT CXMLDOMFromVCDlg::RecExtractThreadCtrlFunc(LPVOID pParam)
{
CXMLDOMFromVCDlg* pDlg = (CXMLDOMFromVCDlg*)pParam;
return pDlg->DoThreadProc();
}
UINT CXMLDOMFromVCDlg::DoThreadProc()
{
// Create object for Single Lock
CSingleLock singleLock(&m_Mutex);
// try to capture the shared resource
singleLock.Lock();
// use the shared resource m_structBlkContSimPara
if(m_structBlkContSimPara.bMod)
{
m_fSimBlkShpWt = m_structBlkContSimPara.fSimBlkShpWt;
m_fSimGrPosWt = m_structBlkContSimPara.fSimGrPosWt;
m_fSimGrTxtAttWt = m_structBlkContSimPara.fSimGrTxtAttWt;
m_fSimGrTypesWt = m_structBlkContSimPara.fSimGrTypesWt;
m_fDataUnitGroupSimThld = m_structBlkContSimPara.fDataUnitGroupSimThld;
m_fVertDistThld = m_structBlkContSimPara.fVertDistThld;
m_structBlkContSimPara.bMod = false;
}
// After we done, let other threads use m_structBlkContSimPara
singleLock.Unlock();
/*some code for data processing*/
}
I am new to multithreading and synchronization. Is my code correct? If not, what should I do to improve it?