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

請教一個 Indy TCPServer 的問題

答題得分者是:lu
jessechan
版主


發表:109
回覆:394
積分:254
註冊:2002-04-05

發送簡訊給我
#1 引用回覆 回覆 發表時間:2003-12-07 02:48:51 IP:61.228.xxx.xxx 未訂閱
int nI = 0;    void __fastcall TForm1::IdTCPServer1Execute(TIdPeerThread *AThread) {   nI++;   Caption = nI; }    以上的 code 在 TCPServer deactivate 時(也就是將 Active 設為 false) 程式會卡住, 但是如果把 Caption = nI; 改成 Caption = Now(); 則一切 OK, 請問要如何解釋.    Jesse Chan
------
Jesse Chan
RaynorPao
版主


發表:139
回覆:3622
積分:7025
註冊:2002-08-12

發送簡訊給我
#2 引用回覆 回覆 發表時間:2003-12-08 11:39:08 IP:203.73.xxx.xxx 未訂閱
引言: int nI = 0; void __fastcall TForm1::IdTCPServer1Execute(TIdPeerThread *AThread) { nI ; Caption = nI; } 以上的 code 在 TCPServer deactivate 時(也就是將 Active 設為 false) 程式會卡住, 但是如果把 Caption = nI; 改成 Caption = Now(); 則一切 OK, 請問要如何解釋. Jesse Chan
jessechan 你好: 請參考以下的寫法 < class="code"> //................................................................. TThreadMethod MyThreadMethod=&ThreadMethod1; AThread->Synchronize(MyThreadMethod); //................................................................. void __fastcall TForm1::ThreadMethod1() { //...Do something... } -- Enjoy Researching & Developing --
------
-- 若您已經得到滿意的答覆,請適時結案!! --
-- 欲知前世因,今生受者是;欲知來世果,今生做者是 --
-- 一切有為法,如夢幻泡影,如露亦如電,應作如是觀 --
lu
高階會員


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

發送簡訊給我
#3 引用回覆 回覆 發表時間:2003-12-08 12:17:17 IP:211.72.xxx.xxx 未訂閱
引言: int nI = 0; void __fastcall TForm1::IdTCPServer1Execute(TIdPeerThread *AThread) { nI ; Caption = nI; } 以上的 code 在 TCPServer deactivate 時(也就是將 Active 設為 false) 程式會卡住, 但是如果把 Caption = nI; 改成 Caption = Now(); 則一切 OK, 請問要如何解釋. Jesse Chan
呵呵~~你犯了一個粉多人會犯的錯誤 就是想要在多執行緒的程式中,操作畫面上的元件 不是不可以,只是有限制.... 大家的想法,不外乎多個THREAD分工合作,或是開一個THREAD專門負責某一些事 這個想法粉好,但是大家都犯了一個錯誤 1. 除了在主THREAD裡,其他的THREAD都不可『直接』操控畫面上的任何東西(包括可視和非可視物件) 所謂的直接是指 Edit1->Text = "1234"; 2. 除了在主THREAD裡,其他的THREAD都不可操作資料庫物件(TDatabase , TTable ,TQuery....等等) 3. 資料鎖定的問題,大家都會用一個BOOL變數來做鎖定,但是這是標準錯誤的作法 先給各位一個簡單的概念,你要一個THREAD分工粉容易,但是你要一個THREAD合作卻粉難。而且你如果迷寫好,Multi Thread程式的效率會比單執行緒的程式還慢喔(這種情況非常容易發生) Multi Thread 程式的寫作複雜度,非常高,足夠寫一大本書了,這就是為啥,粉少有高手願意回應這類的問題,因為不知從何寫起.... 建議各位先找本MultiThread的書來看,先K個3、5遍,再開始寫MultiThread的程式 Win32 多緒程式設計 (Multithreading Applications in Win32) 侯俊傑 譯 碁峰
taishyang
站務副站長


發表:377
回覆:5490
積分:4563
註冊:2002-10-08

發送簡訊給我
#4 引用回覆 回覆 發表時間:2003-12-08 13:57:53 IP:140.135.xxx.xxx 未訂閱
lu您好:
引言: 先給各位一個簡單的概念,你要一個THREAD分工粉容易,但是你要一個THREAD合作卻粉難。而且你如果迷寫好,Multi Thread程式的效率會比單執行緒的程式還慢喔(這種情況非常容易發生) Multi Thread 程式的寫作複雜度,非常高,足夠寫一大本書了,這就是為啥,粉少有高手願意回應這類的問題,因為不知從何寫起.... 建議各位先找本MultiThread的書來看,先K個3、5遍,再開始寫MultiThread的程式
能否請您舉個例子呢? 順心
lu
高階會員


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

發送簡訊給我
#5 引用回覆 回覆 發表時間:2003-12-09 13:14:00 IP:211.72.xxx.xxx 未訂閱
引言: 能否請您舉個例子呢?
呵呵~~版主大人你真的是出各難題給偶了.... 這個範例要寫的簡單,還要說清楚Multi Thread運作的方式,難阿...版主大人 不過...偶還是寫各小程式大家看一下,寫的不好大家多多指教.... 偶寫了一個THREAD,這個THREAD會針對一個數目做加法(或減法)
class TMyThread : public TThread
{
private:
        HANDLE FormHandle; //Form1->Handle
        HANDLE OperationMutex;  //Mutex Object
        unsigned int *Num;
        bool FAddFlag;    //在THREAD是運算加法或減法
        void __fastcall Execute();
public:
        __fastcall TMyThread (HANDLE ttHandle,unsigned int *ttNum,bool AddFlag);
        __fastcall ~TMyThread ()
        {
          CloseHandle (OperationMutex);
        };
};    
lu
高階會員


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

發送簡訊給我
#6 引用回覆 回覆 發表時間:2003-12-09 13:25:43 IP:211.72.xxx.xxx 未訂閱
繼承上例
以下則為程式碼
__fastcall TMyThread::TMyThread (HANDLE ttHandle,unsigned int *ttNum,bool AddFlag)
        : TThread(true)
{
FAddFlag = AddFlag;
Num = ttNum;
FormHandle = ttHandle;
OperationMutex = CreateMutex (NULL,false,"Test Program MyThread Version 1");
}
//---------------------------------------------------------------------------    void __fastcall TMyThread::Execute()
{
int c;    for (c=0;c<100;c  )
  {
    WaitForSingleObject (OperationMutex,INFINITE);
    if (FAddFlag)
      *Num = *Num   1;
    else
      *Num = *Num - 1;
    Sleep (10);      //試著修改看看結果 
    ReleaseMutex (OperationMutex);
    PostMessage  (FormHandle,WM_USER   100 , 0,FAddFlag);
  }
}
//---------------------------------------------------------------------------    void __fastcall TForm1::Button1Click(TObject *Sender)
{
Num = 0;
Memo1->Clear ();
MyThread1->Resume ();
MyThread2->Resume ();
}
//---------------------------------------------------------------------------    void __fastcall TForm1::FormCreate(TObject *Sender)
{
MyThread1 = new TMyThread (this->Handle,&Num,true);
MyThread2 = new TMyThread (this->Handle,&Num,false);
}
//---------------------------------------------------------------------------    void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
MyThread1->WaitFor ();
delete MyThread1;    MyThread2->WaitFor ();
delete MyThread2;
}
//---------------------------------------------------------------------------    void __fastcall TForm1::ShowNumber(TMessage Msg)
{
String ss = "Number:"   (String)Num   ", "   (String)Msg.LParam  ;
Memo1->Lines->Add (ss);
}    
OK 上面的程式,說明了幾件事
  • 在程式之中,如果要運用到『共用資源』(如上例的Num),必須先鎖定
  • 一旦鎖定後,必須盡快放開,否則會降低效率(試著修改Sleep 的參數)
  • 不可在THREAD直接操作畫面上的鍵,除非你非常確定,那個物件是THREAD SAFE
偶這裡用Mutex來做鎖定,各位可試著將 WaitForSingleObject 和 ReleaseMutex取消,然後看看結果 各位也可以是著修改Sleep的數字,看看結果 這個程式粉簡單,產生2個THREAD,一個THREAD對NUM做加法,另外一個則做減法 基本上,最後的結果應該是0,但是卻不一定是這樣... 以上小程式說明了,要2個THREAD分工合作,各位大大請參考 ^^
jessechan
版主


發表:109
回覆:394
積分:254
註冊:2002-04-05

發送簡訊給我
#7 引用回覆 回覆 發表時間:2003-12-09 14:22:27 IP:203.67.xxx.xxx 未訂閱
多謝, 我受益良多.    Jesse Chan
------
Jesse Chan
taishyang
站務副站長


發表:377
回覆:5490
積分:4563
註冊:2002-10-08

發送簡訊給我
#8 引用回覆 回覆 發表時間:2003-12-09 14:44:27 IP:140.135.xxx.xxx 未訂閱
lu您好: 謝謝您熱心的分享< > 順心< >
系統時間:2024-05-05 23:24:31
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!