全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:2782
推到 Plurk!
推到 Facebook!

我使用多線程之後為什麼程式仍然是獨佔CPU?

尚未結案
rambos
一般會員


發表:1
回覆:5
積分:1
註冊:2008-05-11

發送簡訊給我
#1 引用回覆 回覆 發表時間:2008-05-13 19:43:29 IP:58.24.xxx.xxx 訂閱
我有一個程式,初始化工作要花1-2分鐘,比較慢。
我以前沒有採用多線程之前,啟動程式比較慢,並且介面彈出來之後,介面上的所有按鈕都無法使用,因為正在初始化,獨佔了CPU。
所以我後來改用了多線程(multi thread),在FormCreate事件裏面創建線程。
這樣修改之後,沒有達到預期的效果,啟動時還是很慢,介面上的其他按鈕還是無法操作,和以前一樣。
我期望的效果是:程式介面照常彈出來,線程在後臺初始化,我可以在前臺介面上進行一些不依賴於初始化資料的一些操作。
不知道哪里出錯了?我是多線程編程新手,希望各位大大指教!
不勝感激!
線程類中:
__fastcall TMyInitThread::TMyInitThread(bool CreateSuspended)
: TThread(CreateSuspended)
{
}
void __fastcall TMyInitThread::NameSystemInit(void)
{
//ShowMessage("Init Thread0.!");
mainFrm->InitPoetForm();
}
//---------------------------------------------------------------------------
void __fastcall TMyInitThread::Execute()
{
//---- Place thread code here ----
FreeOnTerminate = true;
//Priority = tpIdle;
Synchronize(NameSystemInit);
//mainFrm->InitPoetForm();
}
FormCreate()中的調用:
TMyInitThread* MyThread= new TMyInitThread(true);
MyThread->Resume();
GrandRURU
站務副站長


發表:234
回覆:1651
積分:1742
註冊:2005-06-21

發送簡訊給我
#2 引用回覆 回覆 發表時間:2008-05-14 08:57:22 IP:203.75.xxx.xxx 未訂閱
1.你的線程緩衝時間未定義
2.請善用程式碼區塊功能…
===================引 用 rambos 文 章===================
...43...

[code cpp]
__fastcall TMyInitThread::TMyInitThread(bool CreateSuspended)
: TThread(CreateSuspended)
{
}
void __fastcall TMyInitThread::NameSystemInit(void)
{
//ShowMessage("Init Thread0.!");
mainFrm->InitPoetForm();
}

//---------------------------------------------------------------------------
void __fastcall TMyInitThread::Execute()
{
//---- Place thread code here ----
FreeOnTerminate = true;
//Priority = tpIdle;
Synchronize(NameSystemInit);
//mainFrm->InitPoetForm();
}
FormCreate()中的調用:

TMyInitThread* MyThread= new TMyInitThread(true);
MyThread->Resume();
[/code]
編輯記錄
GrandRURU 重新編輯於 2008-05-14 08:59:39, 註解 無‧
rambos
一般會員


發表:1
回覆:5
積分:1
註冊:2008-05-11

發送簡訊給我
#3 引用回覆 回覆 發表時間:2008-05-14 09:05:03 IP:58.24.xxx.xxx 訂閱

===================引 用 GrandRURU 文 章===================
1.你的線程緩衝時間未定義
2.請善用程式碼區塊功能…
===================引 用 rambos 文 章===================

請問,如何定義線程緩衝時間?我在本論壇沒有找到相關答案。
還有:請善用程式碼區塊功能是什麼意思呢?


能夠給出具體代碼或相關指導文章呢?

thanks a lot!



編輯記錄
rambos 重新編輯於 2008-05-14 09:06:40, 註解 無‧
GrandRURU
站務副站長


發表:234
回覆:1651
積分:1742
註冊:2005-06-21

發送簡訊給我
#4 引用回覆 回覆 發表時間:2008-05-14 09:44:30 IP:203.75.xxx.xxx 未訂閱
關鍵字:sleep

===================引 用 GrandRURU 文 章===================
1.你的線程緩衝時間未定義
2.請善用程式碼區塊功能…
===================引 用 rambos 文 章===================

請問,如何定義線程緩衝時間?我在本論壇沒有找到相關答案。
還有:請善用程式碼區塊功能是什麼意思呢?


能夠給出具體代碼或相關指導文章呢?

thanks a lot!



rambos
一般會員


發表:1
回覆:5
積分:1
註冊:2008-05-11

發送簡訊給我
#5 引用回覆 回覆 發表時間:2008-05-14 10:57:53 IP:58.24.xxx.xxx 訂閱
謝謝大大!
我根據你的提示,查找了一些資料:
如: bruce0211 的《心得分享 : 多執行緒測試》
http://home.kimo.com.tw/bruce0211/

他的文章中:
void __fastcall TMyThread::Execute(void)
{
FreeOnTerminate=true;
while (!Terminated)
{
// Methods and properties of objects in VCL can only be
// used in a method called using Synchronize()
Synchronize(ShowTime); // 要改變 VCL 物件內容必須透過 Synchronize 呼叫
// 不能把 Form1->Edit1->Text=TimeToStr(Now()) 寫在這裡
Sleep(1000);
}
}

所以,我參考了一把我的程式改成:
void __fastcall TMyInitThread::Execute()
{
//---- Place thread code here ----
FreeOnTerminate = true;

Synchronize(NameSystemInit);
Sleep(1);

}

無論是Sleep(1)Sleep(1000)(我知道單位是毫秒),但是沒能達到我要的效果,程式啟動之後,甚至連介面都看不見(白的,有點模糊),CPU還是獨佔,請問,我是不是仍然改得不對呢?

我是新手,謝謝 GrandRURU 兄耐心教導,非常感謝!


===================引 用 GrandRURU 文 章===================
關鍵字:sleep

===================引 用 GrandRURU 文 章===================
1.你的線程緩衝時間未定義
2.請善用程式碼區塊功能…
===================引 用 rambos 文 章===================
請問,如何定義線程緩衝時間?我在本論壇沒有找到相關答案。
還有:請善用程式碼區塊功能是什麼意思呢?


能夠給出具體代碼或相關指導文章呢?

thanks a lot!



rambos
一般會員


發表:1
回覆:5
積分:1
註冊:2008-05-11

發送簡訊給我
#6 引用回覆 回覆 發表時間:2008-05-14 10:59:40 IP:58.24.xxx.xxx 訂閱
我加了
while (!Terminated)
語句,一樣還是不行。。。

===================引 用 rambos 文 章===================
謝謝大大!
我根據你的提示,查找了一些資料:
如: bruce0211 的《心得分享 : 多執行緒測試》
http://home.kimo.com.tw/bruce0211/

他的文章中:
void __fastcall TMyThread::Execute(void)
{
FreeOnTerminate=true;
while (!Terminated)
{
// Methods and properties of objects in VCL can only be
// used in a method called using Synchronize()
Synchronize(ShowTime); // 要改變 VCL 物件內容必須透過 Synchronize 呼叫
// 不能把 Form1->Edit1->Text=TimeToStr(Now()) 寫在這裡
Sleep(1000);
}
}

所以,我參考了一把我的程式改成:
void __fastcall TMyInitThread::Execute()
{
//---- Place thread code here ----
FreeOnTerminate = true;

Synchronize(NameSystemInit);
Sleep(1);

}

無論是Sleep(1)Sleep(1000)(我知道單位是毫秒),但是沒能達到我要的效果,程式啟動之後,甚至連介面都看不見(白的,有點模糊),CPU還是獨佔,請問,我是不是仍然改得不對呢?

我是新手,謝謝 GrandRURU 兄耐心教導,非常感謝!


===================引 用 GrandRURU 文 章===================
關鍵字:sleep

===================引 用 GrandRURU 文 章===================
1.你的線程緩衝時間未定義
2.請善用程式碼區塊功能…
===================引 用 rambos 文 章===================
請問,如何定義線程緩衝時間?我在本論壇沒有找到相關答案。
還有:請善用程式碼區塊功能是什麼意思呢?


能夠給出具體代碼或相關指導文章呢?

thanks a lot!



GrandRURU
站務副站長


發表:234
回覆:1651
積分:1742
註冊:2005-06-21

發送簡訊給我
#7 引用回覆 回覆 發表時間:2008-05-14 13:45:48 IP:203.75.xxx.xxx 未訂閱
執行緒停止之後耗用量就變成零了嗎?
執行緒內的函式是做了些什麼事呢?
ikk
尊榮會員


發表:4
回覆:413
積分:768
註冊:2003-06-30

發送簡訊給我
#8 引用回覆 回覆 發表時間:2008-05-14 17:44:05 IP:140.116.xxx.xxx 訂閱
應該是出在這個呼叫, 試著把InitPoetForm();放到thread裡面執行.
而不是去呼叫mainFrm執行.

[code cpp]
void __fastcall TMyInitThread::NameSystemInit(void)
{
//ShowMessage("Init Thread0.!");
mainFrm->InitPoetForm();
}
[/code]
------
FPGA驗證, FPGA開發平台, http://smims.com
編輯記錄
ikk 重新編輯於 2008-05-14 17:44:44, 註解 無‧
wjhsu
初階會員


發表:9
回覆:32
積分:48
註冊:2004-06-13

發送簡訊給我
#9 引用回覆 回覆 發表時間:2008-05-15 00:25:16 IP:123.195.xxx.xxx 訂閱
請試試將Thread的Priority 設為tpLower以下, 然後將要初始化的程式都在Thread執行...
另外, 在Thread裏用Synchronize(), 好像就會排到VCL的主迴圈執行
就像在ma
<iframe width="100%" height="100%" frameborder="0" src="void(0)" ></iframe>
inFrm執行一樣(請參考其它大大們的討論有提到過..)
lu
高階會員


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

發送簡訊給我
#10 引用回覆 回覆 發表時間:2008-05-16 10:10:17 IP:203.73.xxx.xxx 訂閱
用了Multi Thread 還會很慢的原因,是因為你在 THREAD 呼叫 Synchronize 

看你寫的CODE,我猜你大概是第一次寫 MultiThread 的程式,給你一個建議,請先找本 Multi Thread 的書看一看,再來寫
不然很容易寫出3不5時就跳出ERROR MESSAGE的程式

我猜你在Synchronize 裡面會使用到畫面上的可視元件(如TEdit , TListBox 等等之類)甚至是 Database 的物件,如果有~~請不要把Synchronize 去掉,直接呼叫NameSystemInit ,因為M$ 規定除了 Main Thread 以外,不可以在其他THREAD之中直接操作畫面上的元件(例如: Edit1->Text = "test"; ),相關說明請參閱 MSDN 有關 THREAD 的相關說明

另外,站上有很多有關THREAD的討論,請先爬一下文章

===================引 用 rambos 文 章===================
我有一個程式,初始化工作要花1-2分鐘,比較慢。
我以前沒有採用多線程之前,啟動程式比較慢,並且介面彈出來之後,介面上的所有按鈕都無法使用,因為正在初始化,獨佔了CPU。
所以我後來改用了多線程(multi thread),在FormCreate事件裏面創建線程。
這樣修改之後,沒有達到預期的效果,啟動時還是很慢,介面上的其他按鈕還是無法操作,和以前一樣。
我期望的效果是:程式介面照常彈出來,線程在後臺初始化,我可以在前臺介面上進行一些不依賴於初始化資料的一些操作。
不知道哪里出錯了?我是多線程編程新手,希望各位大大指教!
不勝感激!
線程類中:

[code cpp]
__fastcall TMyInitThread::TMyInitThread(bool CreateSuspended)
: TThread(CreateSuspended)
{
}
void __fastcall TMyInitThread::NameSystemInit(void)
{
//ShowMessage("Init Thread0.!");
mainFrm->InitPoetForm();
}
//---------------------------------------------------------------------------
void __fastcall TMyInitThread::Execute()
{
//---- Place thread code here ----
FreeOnTerminate = true;
//Priority = tpIdle;
Synchronize(NameSystemInit);
//mainFrm->InitPoetForm();
}
[/code]
FormCreate()中的調用:
TMyInitThread* MyThread= new TMyInitThread(true);
MyThread->Resume();
rambos
一般會員


發表:1
回覆:5
積分:1
註冊:2008-05-11

發送簡訊給我
#11 引用回覆 回覆 發表時間:2008-05-16 11:42:38 IP:58.24.xxx.xxx 訂閱

非常感激lu,ikkGrandRURU兄!
lu兄果然法眼無礙!
我的確第一次寫MultiThread 程式,所以只是依貓畫虎,讓你見笑了:)
我在幾年前第一次接觸該論壇,就被這裏吸引,並且我一直以來深深感佩臺灣論壇於大陸論壇之不同(比如大陸的csdn
在大陸技術論壇往往是問問題的多,真正熱心回答的少,並且往往回了幾貼之後,內容就扯遠了,與主題無關了。
實在讓人歎息。。。
而反觀在本論壇上,很多熱心大大親自測試調試網友提出來的問題,多方尋求答案,實在讓人感動!臺灣同胞治學嚴謹實在讓人敬佩,我不止一次向我朋友提起。

我再把我的程式情況彙報如下:

我在InitPoetForm進行了如下操作:
主要是從兩個很大的檔中讀取資料登錄到哈希表(map)中,這兩個檔分別有400多萬行,我這樣做的目的其實也是以空間換時間之故。

void __fastcall TmainFrm::InitPoetForm(void)
{
//PoetNameForm中的初始化內容
tmrInit->Enabled = false;
///////////////////////////////////////////////////////////////////////////
String mapFile,idxFile,poetFile;
poetFile = mainFrm->GetPoetTxtFileName();
mapFile = mainFrm->GetPoetIdxFileName();
idxFile = mainFrm->GetWxIdxFileName();
String mTmpSaveFileName = "c:\\winrar0008._i_";
//mPoetsTxtList->LoadFromFile(poetFile);
//初始化multiMap
frmPoetNameForm->gHzMap.clear();
frmPoetNameForm->gWxIdxMap.clear();
TStringList * tmpList = new TStringList();
tmpList->Clear();
tmpList->LoadFromFile(mapFile);
String line,hz,idx;
for( long i = 0; i < tmpList->Count; i )
{
line = tmpList->Strings[i];
hz = line.SubString(1,2);
idx = line.SubString(3,line.Length()-2);
frmPoetNameForm->gHzMap.insert(make_pair(hz,idx));
}
//初始化索引
tmpList->Clear();
tmpList->LoadFromFile(idxFile);
for( long i = 0; i < tmpList->Count; i )
{
line = tmpList->Strings[i];
frmPoetNameForm->gWxIdxMap.insert(make_pair(i,line));
}
tmpList->Clear();
memoMain->Lines->Clear();
MessageBox(NULL,"程式初始化工作已經完成,點擊[確定]之後你便可盡情使用本程式!","恭喜發財!",MB_ICONEXCLAMATION);
///////////////////////////////////////////////////////////////////////////
}
其中:

frmPoetNameForm->gHzMap.clear();
frmPoetNameForm->gWxIdxMap.clear();

這兩個gHzMapgWxIdxMap是在另外一個frmPoetNameForm中使用的。
如果我把上述代碼直接放在Thread中,同時去掉與畫面上的元件有關的操作,同時去掉Synchronize這種調用,
是否需要進行一些改造呢?
ThreadmainFrm->GetPoetTxtFileName(),這樣調用mainFrm中的函數,行嗎?

最後,為深切在中國四川5.12大地震中喪生的百姓表示深切哀悼,希望早日度過難關!
感謝臺灣同胞捐贈的救援物質!謝謝!


=================== lu ===================
用了Multi Thread 還會很慢的原因,是因為你在 THREAD 呼叫 Synchronize

看你寫的CODE,我猜你大概是第一次寫 MultiThread 的程式,給你一個建議,請先找本 Multi Thread 的書看一看,再來寫
不然很容易寫出35時就跳出ERROR MESSAGE的程式

我猜你在Synchronize 裡面會使用到畫面上的可視元件(如TEdit , TListBox 等等之類)甚至是 Database 的物件,如果有~~請不要把Synchronize 去掉,直接呼叫NameSystemInit ,因為M$ 規定除了 Main Thread 以外,不可以在其他THREAD之中直接操作畫面上的元件(例如: Edit1->Text = "test"; ),相關說明請參閱 MSDN 有關 THREAD 的相關說明

另外,站上有很多有關THREAD的討論,請先爬一下文章
///////////////////////////////////////////////////////////////////////////////////////////


lu
高階會員


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

發送簡訊給我
#12 引用回覆 回覆 發表時間:2008-05-16 12:36:10 IP:203.73.xxx.xxx 訂閱
坦白說, gHzMapgWxIdxMap 可不可以在 Thread 使用,這個問題,大概要你自己才有辦法回答了

因為除了你自己,誰也不知道該元件用了什麼東西?可不可以在THREAD直接操作

給你一個方向,你在論壇上可以找一下有關 ThreadSafe 相關的文章,論壇上有很多相關的討論,我不再重複

===================引 用 rambos 文 章===================

非常感激lu,ikkGrandRURU兄!
lu兄果然法眼無礙!
我的確第一次寫MultiThread 程式,所以只是依貓畫虎,讓你見笑了:)
我在幾年前第一次接觸該論壇,就被這裏吸引,並且我一直以來深深感佩臺灣論壇於大陸論壇之不同(比如大陸的csdn
在大陸技術論壇往往是問問題的多,真正熱心回答的少,並且往往回了幾貼之後,內容就扯遠了,與主題無關了。
實在讓人歎息。。。
而反觀在本論壇上,很多熱心大大親自測試調試網友提出來的問題,多方尋求答案,實在讓人感動!臺灣同胞治學嚴謹實在讓人敬佩,我不止一次向我朋友提起。

我再把我的程式情況彙報如下:

我在InitPoetForm進行了如下操作:
主要是從兩個很大的檔中讀取資料登錄到哈希表(map)中,這兩個檔分別有400多萬行,我這樣做的目的其實也是以空間換時間之故。

void __fastcall TmainFrm::InitPoetForm(void)
{
//PoetNameForm中的初始化內容
tmrInit->Enabled = false;
///////////////////////////////////////////////////////////////////////////
String mapFile,idxFile,poetFile;
poetFile = mainFrm->GetPoetTxtFileName();
mapFile = mainFrm->GetPoetIdxFileName();
idxFile = mainFrm->GetWxIdxFileName();
String mTmpSaveFileName = "c:\\winrar0008._i_";
//mPoetsTxtList->LoadFromFile(poetFile);
//初始化multiMap
frmPoetNameForm->gHzMap.clear();
frmPoetNameForm->gWxIdxMap.clear();
TStringList * tmpList = new TStringList();
tmpList->Clear();
tmpList->LoadFromFile(mapFile);
String line,hz,idx;
for( long i = 0; i < tmpList->Count; i )
{
line = tmpList->Strings[i];
hz = line.SubString(1,2);
idx = line.SubString(3,line.Length()-2);
frmPoetNameForm->gHzMap.insert(make_pair(hz,idx));
}
//初始化索引
tmpList->Clear();
tmpList->LoadFromFile(idxFile);
for( long i = 0; i < tmpList->Count; i )
{
line = tmpList->Strings[i];
frmPoetNameForm->gWxIdxMap.insert(make_pair(i,line));
}
tmpList->Clear();
memoMain->Lines->Clear();
MessageBox(NULL,"程式初始化工作已經完成,點擊[確定]之後你便可盡情使用本程式!","恭喜發財!",MB_ICONEXCLAMATION);
///////////////////////////////////////////////////////////////////////////
}
其中:

frmPoetNameForm->gHzMap.clear();
frmPoetNameForm->gWxIdxMap.clear();

這兩個gHzMapgWxIdxMap是在另外一個frmPoetNameForm中使用的。
如果我把上述代碼直接放在Thread中,同時去掉與畫面上的元件有關的操作,同時去掉Synchronize這種調用,
是否需要進行一些改造呢?
ThreadmainFrm->GetPoetTxtFileName(),這樣調用mainFrm中的函數,行嗎?

最後,為深切在中國四川5.12大地震中喪生的百姓表示深切哀悼,希望早日度過難關!
感謝臺灣同胞捐贈的救援物質!謝謝!


=================== lu ===================
用了Multi Thread 還會很慢的原因,是因為你在 THREAD 呼叫 Synchronize

看你寫的CODE,我猜你大概是第一次寫 MultiThread 的程式,給你一個建議,請先找本 Multi Thread 的書看一看,再來寫
不然很容易寫出35時就跳出ERROR MESSAGE的程式

我猜你在Synchronize 裡面會使用到畫面上的可視元件(如TEdit , TListBox 等等之類)甚至是 Database 的物件,如果有~~請不要把Synchronize 去掉,直接呼叫NameSystemInit ,因為M$ 規定除了 Main Thread 以外,不可以在其他THREAD之中直接操作畫面上的元件(例如: Edit1->Text = "test"; ),相關說明請參閱 MSDN 有關 THREAD 的相關說明

另外,站上有很多有關THREAD的討論,請先爬一下文章
///////////////////////////////////////////////////////////////////////////////////////////


rambos
一般會員


發表:1
回覆:5
積分:1
註冊:2008-05-11

發送簡訊給我
#13 引用回覆 回覆 發表時間:2008-06-02 11:47:29 IP:58.24.xxx.xxx 訂閱
谢谢各位,虽然问题没有解决,我后来优化了初始化的算法,速度已经得到了改善。
系統時間:2017-10-23 3:16:32
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!