求大神幫幫忙!!!在初始化這個視窗的時候,初始化執行緒的引數,然后啟用執行緒,獲取相關串口資料,但是為什么點擊關閉的時候,然后就進入死回圈不管用,執行緒也關閉不了?





uj5u.com熱心網友回復:
求大神幫幫忙啊uj5u.com熱心網友回復:
增加一個執行緒退出標記, CommThread 中 判斷這個標記 while(! bThreadExit) { ……}uj5u.com熱心網友回復:
有一個end_thread的退出標記啊uj5u.com熱心網友回復:
有一個endtgread標記了,在退出的時候已經setevent了uj5u.com熱心網友回復:
請 復制 文字,不要圖片 !uj5u.com熱心網友回復:
由于代碼屬于比較私密環境下的,電腦不能上網,不能插u盤,所以請見諒uj5u.com熱心網友回復:
貼上代碼BOOL Sdcs::OnInitDialog()
{
CDialogEx::OnInitDialog();
//初始化執行緒的引數
InitEvent();
StartMonitoring();
}
void Sdcs::InitEvent()
{
m_Start = CreateEvent(NULL, TRUE, FALSE, NULL);
m_Pause = CreateEvent(NULL, TRUE, FALSE, NULL);
m_EndThread = CreateEvent(NULL, TRUE, FALSE, NULL);
m_hEventArray[0] = m_Start;
m_hEventArray[1] = m_Pause;
m_hEventArray[2] = m_EndThread;
m_bThreadAlive = FALSE;
}
//啟動執行緒
BOOL Sdcs::StartMonitoring()
{
if (!(m_Thread = AfxBeginThread(CommThread, this)))
{
return FALSE;
}
ResetEvent(m_EndThread);
TRACE("Thread started\n");
return TRUE;
}
UINT Sdcs::CommThread(LPVOID pParam) {
Sdcs *mycmd = (Sdcs*)pParam;
DWORD Event = 0;
mycmd->m_bThreadAlive = TRUE;
while (1)
{
Event = WaitForMultipleObjects(3, mycmd->m_hEventArray, FALSE, 0);
if (Event = WAIT_TIMEOUT){運用超時實時顯示從串口接收的資料}
else if (Event == 0)
{
}
else if (Event == 1)
{
}
else if (Event == 2)
{
ResetEvent(mycmd->m_EndThread);
break;
}
else
{
break;
}
}
mycmd->m_bThreadAlive = FALSE;
return 0;
}
void Sdcs::OnClose()
{
// TODO: 在此添加訊息處理程式代碼和/或呼叫默認值
CDialogEx::OnClose();
if (m_IsOpen)
{
while (m_bThreadAlive)
{
SetEvent(m_EndThread);
}
m_port.PortClose();
}
m_IsOpen = FALSE;
}
然后點擊關閉,直接卡死死回圈了;
跪求各位大神幫忙!!!
uj5u.com熱心網友回復:
while (m_bThreadAlive) 這句 ?AfxBeginThread(CommThread, this))) 可以 自動 退出,(見1 樓),用太多 event 不好 !
參考
// use ON_MESSAGE(a,b)
void CUload::OnCommNotify(WPARAM wParam,LPARAM lParam)
{
// TODO: Add your specialized code here and/or call the base class
int nLength;
BYTE abIn[6000];// for 115200 needs 4096 and more
DWORD totalrecv;
CString txt;
switch(wParam)
{
case 0:// from CommWatchCTS()
SetCTSIcon();
SetEvent(m_hPostEventRead);// tell watcher that CommNotify has been done
break;
case 1:// from CommWatchRead()
// append on each entry
CFile uldFile(UpLoadFileName,CFile::modeCreate|CFile::modeNoTruncate|CFile::modeWrite);
uldFile.SeekToEnd( );
if (m_bConnected)
{
if(nLength=ReadCommBlock(abIn,BUFLEN))// 38400 needs 1024
{ // save into file
if (!m_bStart)
{ // only 1st
m_bStart=1;
InforOut("Receiving "+UpLoadFileName);
}
uldFile.Write(abIn,nLength);
}
}
uldFile.Close();
// get total bytes received
m_uldINs.GetText(0,txt);
totalrecv=atol(txt.GetBuffer(40));
totalrecv+=nLength;
txt.Format("%d",totalrecv);
m_uldINs.ResetContent();
m_uldINs.AddString(txt);
if (nLength>128)
{
Animate();
// reset "time waiting"
m_Elapse.ResetContent();
m_Elapse.AddString("0 s");
}
// tell watcher that CommNotify has been done
SetEvent(m_hPostEventRead);
break;
}
}
uj5u.com熱心網友回復:
你只用一次SetEvent,然后在等待Thread退出,WaitForSingleObject(hThread, INFINITE);uj5u.com熱心網友回復:
SetEvent這種代碼寫起來不太好寫的. 而且要Wait等待可以用變數來控制! 但變數要 volatile 的! 注意這個! 否則可能變數改變之后, 另外的執行緒取到的還是老資料. 被暫存器快取了.
uj5u.com熱心網友回復:
m_bThreadAlive 這個改成 volatile 的uj5u.com熱心網友回復:
退出時 給執行緒發送PostThreadMessage(threadid, WM_QUIT, 0, 0)uj5u.com熱心網友回復:
void Sdcs::OnClose()
{
// TODO: 在此添加訊息處理程式代碼和/或呼叫默認值
CDialogEx::OnClose();
if (m_IsOpen)
{
while (m_bThreadAlive)
{
SetEvent(m_EndThread);
}
m_port.PortClose();
}
m_IsOpen = FALSE;
}
你把CDialogEx::OnClose();放在最前邊不好吧。
另外m_bThreadAlive定義的時候改為 volatile bool m_bThreadAlive; 試試
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/57526.html
標籤:進程/線程/DLL
