線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:3419
推到 Plurk!
推到 Facebook!

請問關於Thread無法Terminate的問題

答題得分者是:lu
timlong
一般會員


發表:4
回覆:5
積分:1
註冊:2007-04-18

發送簡訊給我
#1 引用回覆 回覆 發表時間:2007-04-18 16:37:32 IP:210.68.xxx.xxx 訂閱
大家好:

我的程式Fom1可以呼叫Form3->show();

void __fastcall TForm1::CommendClick(TObject *Sender)
{
Form3->Show();
}

然後在Form3啟動一個執行緒A,

A->Resume();



A的程式如下:

void __fastcall CNMEA_Receiver::Execute()
{


SetName();
//以下為接收NMEA資料的程式
while(!Terminated)
{


int ch=0;
int i=0;
int size_of_NMEA=0;
AnsiString check_which_message="";
for(i=0;i<512;i )
{
gRS232.RS232RXBuf[i]=0;

}

ch=getch_Sleep();

if(ch==36) //假如回傳的是"$"
{
while(ch!=10&&size_of_NMEA<512)
{
if(ch>0)
{
gRS232.RS232RXBuf[size_of_NMEA ]=ch;
}

ch=getch_Sleep(); //取得下一個字元
}

//再附加一個字元10
gRS232.RS232RXBuf[size_of_NMEA ]=ch;


//取得前六字元當辨識字
for(int i=0;i<6;i )
check_which_message =(char)gRS232.RS232RXBuf[i];

//秀出nmea
Form4->Memo1->Lines->Add(CharStarToStr(gRS232.RS232RXBuf));
}



if(Form4->Memo1->Lines->Count>=500)
{
Form4->Memo1->Lines->Clear();
}


//-----------------------------Begin------------寫入檔案--------------------------------
if(Form3->logFile.is_open())
{
for(int i=0;i Form3->logFile<<(char)gRS232.RS232RXBuf[i];
}
//-----------------------------End------------寫入檔案--------------------------------



//---------------------------------進行checksum和資料Parse---------------------------

if(check_which_message=="$GPGGA"&&size_of_NMEA<256)
{
//when return is true

if(GPS_NMEA_Cksum(gRS232.RS232RXBuf,gRS232.RS232RXBuf[size_of_NMEA-4],gRS232.RS232RXBuf[size_of_NMEA-3]))
{
//NMEA parse and get GPGGA data
NMEA_GPGGA.getAll(gRS232.RS232RXBuf);
}
//ShowNMEA.showGPGGA();
}
else if(check_which_message=="$GPGLL"&&size_of_NMEA<256)
{
if(GPS_NMEA_Cksum(gRS232.RS232RXBuf,gRS232.RS232RXBuf[size_of_NMEA-4],gRS232.RS232RXBuf[size_of_NMEA-3]))
{
NMEA_GPGLL.getAll(gRS232.RS232RXBuf);
}

if (NMEA_GPGLL.status=="V")//判斷資料是否可用
{

// ShowNMEA.showGPGLL();
}
}
else if(check_which_message=="$GPGSA"&&size_of_NMEA<256)
{
if(GPS_NMEA_Cksum(gRS232.RS232RXBuf,gRS232.RS232RXBuf[size_of_NMEA-4],gRS232.RS232RXBuf[size_of_NMEA-3]))
{
NMEA_GPGSA.getAll(gRS232.RS232RXBuf);

}

//ShowNMEA.showGPGSA();
}
else if(check_which_message=="$GPGSV"&&size_of_NMEA<256)
{
if(GPS_NMEA_Cksum(gRS232.RS232RXBuf,gRS232.RS232RXBuf[size_of_NMEA-4],gRS232.RS232RXBuf[size_of_NMEA-3]))
{
NMEA_GPGSV.getAll(gRS232.RS232RXBuf);
}
//ShowNMEA.showGPGSV();
}
else if(check_which_message=="$GPRMC"&&size_of_NMEA<256)
{
if(GPS_NMEA_Cksum(gRS232.RS232RXBuf,gRS232.RS232RXBuf[size_of_NMEA-4],gRS232.RS232RXBuf[size_of_NMEA-3]))
{
NMEA_GPRMC.getAll(gRS232.RS232RXBuf);
//------------------------------------
if (NMEA_GPRMC.status=="A")//判斷是否是可用資料
{
//ShowNMEA.showGPRMC();
}
}
}
else if(check_which_message=="$GPVTG"&&size_of_NMEA<256)
{
if(GPS_NMEA_Cksum(gRS232.RS232RXBuf,gRS232.RS232RXBuf[size_of_NMEA-4],gRS232.RS232RXBuf[size_of_NMEA-3]))
{
NMEA_GPRMC.getAll(gRS232.RS232RXBuf);
}
}
else
;


}


}


當在Form1關閉時,Form3也會關閉,但是這時會出現
EOSError-System Error. Code: 5

我推測是Form3所啟動的thread A沒有停掉
於是我加入Form3->A->Terminate();在close Form1的程式碼內,

void __fastcall TForm1::ExitClick(TObject *Sender)
{


Form3->A->Terminate();
Close();
}

但是依舊會出現一樣的錯誤訊息,



我在Form1關閉前, 寫程式如下




void __fastcall TForm1::ExitClick(TObject *Sender)
{

Form3->A->WaitFor();
Form3->A->Terminate();
Close();
}


然後按F9,但是如此一來,會出現程式當住的情況,無法順利關閉Form1

不知道是否有順利可以停止thread的方法,謝謝
lu
高階會員


發表:11
回覆:189
積分:195
註冊:2003-11-19

發送簡訊給我
#2 引用回覆 回覆 發表時間:2007-04-24 09:22:31 IP:203.73.xxx.xxx 訂閱
你好~~看了一下你的程式碼,你犯了一個錯誤,在THREAD之中不可直接操作不是THREAD SAFE的VCL
例如:
Form4->Memo1->Lines->Ad(xxxxxx);

至於那一個東西是THREAD SAFE?最簡單的辦法就是看HELP,一般來說除非HELP有明確說該物件是THREAD SAFE,不然你都應該當成是NO THREAD SAFE

偶若沒猜錯,這是你第一次接觸THREAD的程式
給你一個建議,若要寫MULTI THREAD的程式之前,先去找本MULTI THREAD的書來K一下,因為MULTI THREAD的程式,有一個特點就是,如果因為你寫錯,導致發生問題時,程式會『亂當』,所謂的『亂當』就是,可能執行1分鐘之後出現問題,也有可能1個小時後才出問題,偶還遇過寫好自己測試都OK,但是一放到客戶那邊就掛

參考看看吧
timlong
一般會員


發表:4
回覆:5
積分:1
註冊:2007-04-18

發送簡訊給我
#3 引用回覆 回覆 發表時間:2007-04-24 13:46:38 IP:210.68.xxx.xxx 訂閱
原來如此,多謝您的回答,讓我受益良多,您說的沒錯,我是剛接觸thread的新手,謝謝

此外若我只有一 個thread會操作這個VCL 這樣也會出現問題嗎 ?
(即程式看到的那一行Form4->memo->Lines->add())

是否可以請您請舉出一些safe的VCL,讓小弟比較看看 謝謝
編輯記錄
timlong 重新編輯於 2007-04-24 13:49:10, 註解 無‧
timlong 重新編輯於 2007-04-24 14:47:02, 註解 無‧
lu
高階會員


發表:11
回覆:189
積分:195
註冊:2003-11-19

發送簡訊給我
#4 引用回覆 回覆 發表時間:2007-04-24 15:22:10 IP:203.73.xxx.xxx 訂閱
是的,也會出問題,恩~~正確的說法應該是,可能會出問題,為啥說『可能』會出問題,因為這個舉動本來就是不合法低(詳情請查閱MSDN,MSDN關於THREAD的部分有說明)舉例來說,闖紅燈可能會車禍,不代表每次闖都會有事

至於哪些VCL是THREAD SAFE,應該說大部分的VCL都是NOT THREAD SAFE(這部分BORLAND也有說明),這邊說個原則,一般來說,你在設計階段,可以拖拉放在FORM上的可視元件(如 TEdit , TComboBox , TMemo 等等),都不是 Thread Safe(當然凡事都有例外,但是這樣的例外太少,可忽略),而目前偶確定的THREAD SAFE的是 AnsiString, WideString, TDateTime,TADOxxxxx (如 TADOConnection , TADOQuery 等等,不過這幾個元件是繼承 M$ 的 ADO ,而M$ 的 ADO 本來就是支援 Multi Thread.....所以.....)

至於你要在THREAD執行 Form4->memo->Lines->add() ,有兩種方案可實現

1. 在THREAD之中呼叫 Synchronize()
2. 在THREAD利用 SendMessage or PostMessage 將訊息傳給FORM,由FORM再去處理相關事宜

以上兩種用法,查一下K.TOP吧,這方面有許多討論


===================引 用 timlong 文 章===================
原來如此,多謝您的回答,讓我受益良多,您說的沒錯,我是剛接觸thread的新手,謝謝

此外若我只有一 個thread會操作這個VCL 這樣也會出現問題嗎 ?
(即程式看到的那一行Form4->memo->Lines->add())

是否可以請您請舉出一些safe的VCL,讓小弟比較看看 謝謝
編輯記錄
lu 重新編輯於 2007-04-25 08:26:31, 註解 無‧
timlong
一般會員


發表:4
回覆:5
積分:1
註冊:2007-04-18

發送簡訊給我
#5 引用回覆 回覆 發表時間:2007-04-24 17:41:23 IP:140.117.xxx.xxx 訂閱
謝謝,不勝感激
系統時間:2024-04-26 21:17:39
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!