我使用多線程之後為什麼程式仍然是獨佔CPU? |
答題得分者是:小傑克
|
bluesum
一般會員 發表:3 回覆:11 積分:2 註冊:2009-05-09 發送簡訊給我 |
各位好
我剛學習寫muti thread, 我己看過 http://delphi.ktop.com.tw/board.php?cid=168&fid=923&tid=93670 但是我使用多線程之後為什麼程式仍然是獨佔CPU 我的來源碼 : http://home.i-cable.com/wu/testduel.zip 測試雙綫程在 TestduelbuttonClick. 不知道哪里出錯了? 多謝各位先 |
chih_kuan
中階會員 發表:38 回覆:82 積分:54 註冊:2003-02-20 發送簡訊給我 |
|
bluesum
一般會員 發表:3 回覆:11 積分:2 註冊:2009-05-09 發送簡訊給我 |
===================引 用 chih_kuan 文 章=================== 請在 Execute 程序中..加上一行 Sleep(1); [code delphi] procedure TAIThrd.Execute; var a,b:integer; begin // if not assigned(pointer(Fthreadno)) then // Fthreadno:=1; // if not assigned(pointer(Fcancut)) then // Fcancut :=True; Sleep(1); // <--加在這裏 ? 依然唔得. strtoboard; if Fthreadno = 1 then Fthinkstep:=ThinkNumber(AIboard,FAIcolor,FRealdepth) else Fthinkstep:=ThinkNumber(AIboard,FAIcolor,FRealdepth-1); ........ [/code]
編輯記錄
bluesum 重新編輯於 2009-05-11 20:19:28, 註解 無‧
|
bluesum
一般會員 發表:3 回覆:11 積分:2 註冊:2009-05-09 發送簡訊給我 |
我不知道為何只有這樣測試質數才沒問題
[code delphi] unit PrimeForm; // http://www.pergolesi.demon.co.uk/prog/threads/Ch2.html interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls,SyncObjs; type TPrimeNotifyEvent = procedure(const TestNum:string;const Realprime: Boolean) of object; TPrimeThrd = class(TThread) private FTestNumber: integer; FPrimeResult: boolean; FPrimeNotifyEvent: TPrimeNotifyEvent; protected // function IsPrime: boolean; procedure IsPrime; procedure Execute; override; procedure Call; public property TestNumber: integer write FTestNumber; property PrimeResult: boolean read FPrimeResult; property PrimeNotifyEvent :TPrimeNotifyEvent read FPrimeNotifyEvent write FPrimeNotifyEvent; // Published end; type TPrimeFrm = class(TForm) NumEdit: TEdit; Button2: TButton; Memo1: TMemo; procedure OnPrimeNotifyEvent(const Testnumber:string;const Realprime:boolean); procedure DoubleThread(const num:integer); procedure Button2Click(Sender: TObject); procedure FormCreate(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); private Listbox1:TStringList; LockLIST:TCriticalSection; uncounted:integer; testa,testb:boolean; { Private declarations } public rectime:Tdatetime; { Public declarations } end; var PrimeFrm: TPrimeFrm; implementation //uses PrimeThread; {$R *.dfm} Procedure TPrimeThrd.IsPrime; var iter: integer; begin FPrimeResult := True; if FTestNumber < 0 then begin FPrimeResult := false; exit; end; if FTestNumber <= 2 then exit; for iter := 2 to FTestNumber - 1 do begin if (FTestNumber mod iter) = 0 then begin FPrimeResult := False; exit; {exit;} end; end; end; procedure TPrimeThrd.Execute; //var a:boolean; begin IsPrime; if assigned(PrimeNotifyEvent) then Synchronize(Call); end; procedure TPrimeThrd.Call; begin PrimeNotifyEvent(intTostr(FTestNumber),FPrimeResult); end; procedure TPrimeFrm.OnPrimeNotifyEvent(const Testnumber:string;const Realprime:boolean); var a:integer; begin LockList.Acquire; memo1.lines.add(Testnumber ' ' BoolToStr(Realprime,True)); a:= 123456789-strToint(Testnumber)-90; Listbox1[a 90] := 'y'; if a = -1 then begin if testb then begin memo1.lines.add('finish'); end; testa := true; LockList.Release; exit; end; if a = 0 then begin if testa then begin memo1.lines.add('finish'); end; testb := true; LockList.Release; exit; end; a:= listbox1.IndexOf(' '); a:= 123456789-a; // a:=strtoint(Testnumber)-2; DoubleThread(a); end; procedure TPrimeFrm.DoubleThread(const num:integer); var NewThread: TPrimeThrd; begin NewThread := TPrimeThrd.Create(True); NewThread.FreeOnTerminate := True; NewThread.TestNumber := num; NewThread.PrimeNotifyEvent := OnPrimeNotifyEvent; NewThread.Resume; end; procedure TPrimeFrm.FormClose(Sender: TObject; var Action: TCloseAction); begin Listbox1.Free; LockLIST.Destroy; end; procedure TPrimeFrm.FormCreate(Sender: TObject); begin Listbox1:=Tstringlist.Create; LockLIST:=TCriticalSection.Create; end; procedure TPrimeFrm.Button2Click(Sender: TObject); var a:integer; begin // Method3a:=False; // Method3b:=False; memo1.Clear; // uncounted:= 90; listbox1.Clear; for a:= 1 to 100 do listbox1.Add(' '); DoubleThread(123456789); DoubleThread(123456788); end; end. [/code] |
小傑克
資深會員 發表:5 回覆:209 積分:357 註冊:2009-02-16 發送簡訊給我 |
------
額有朝天骨,眼中有靈光 |
bluesum
一般會員 發表:3 回覆:11 積分:2 註冊:2009-05-09 發送簡訊給我 |
我的目的是想雙核心cpu的同時盡力做野
===================引 用 小傑克 文 章=================== http://delphi.ktop.com.tw/board.php?cid=30&fid=1498&tid=97825 剛好這篇討論中我有寫個測試, 你可以用簡單的程式感受一下差別在哪邊 |
小傑克
資深會員 發表:5 回覆:209 積分:357 註冊:2009-02-16 發送簡訊給我 |
就我的理解是這樣,mutli- thread 跟雙cpu 是沒關聯的, 雙cpu運用 是由系統分配, 除非你程式中指定cpu
在http://delphi.ktop.com.tw/board.php?cid=168&fid=923&tid=90685 有提到,但是我沒雙cpu,也沒這樣試過 就我的理解在mutli-thread程式中, 就像賣電影票的窗口和外面排隊的人群, 有沒有用Synchronize() 對於系統 (os), 就像有沒有警察在維持排隊的秩序, 當你用Synchronize時, 外面人雖然排很多,但是警察(delphi)會維持秩序確保只有一排隊伍, 好處是Synchronize 由delphi底層幫你做memory control 的事,例如thread共用golbal 變數, 或是某些VCL, 壞處是ap不會去壓榨os , 而當沒用Synchronize時 , 脫序的群眾一擁而上去捶打賣票的窗口(os), 這時os 如果有辦法的話, 也許會多開兩個窗口一起賣票, 但這決定權, 是在os 上,不是ap決定的, 如果售票小姐只有一個, 同時開十個窗口(10-thread waiting) 也沒用,只是一個小姐跑來跑去而已,但至少這個小姐會很忙,不會一邊看報紙一邊吃便當一邊講手機一邊賣票 我注意到你在thread 的execute 中用Synchronize(call) 而在call 這個function 中做PrimeNotifyEvent , 而PrimeNotifyEvent 中你又使用LockList , 根據說明 , LockList 是通知os 由os 來確保只有一個thread 在執行.....我不知道LockList 在多cpu機器中具體的運作是怎樣, 但我猜LockList 實現的方法還是讓Lock / unlock 期間的程式同一時間只有一個在執行 我之前貼的那個小測試程式,主要是測試 Synchronize (我有remark 起來), Application.ProcessMessages, sleep(1) 這三個,這三個對結果都是有影響的,你可以試試沒有Synchronize 沒有sleep的時候的狀況, 再加大一點cpu忙碌程度試試看(比如跑個1 - 50000萬空for loop的)
------
額有朝天骨,眼中有靈光
編輯記錄
小傑克 重新編輯於 2009-05-13 03:18:13, 註解 無‧
|
bluesum
一般會員 發表:3 回覆:11 積分:2 註冊:2009-05-09 發送簡訊給我 |
===================引 用 小傑克 文 章=================== 就我的理解是這樣,mutli- thread 跟雙cpu 是沒關聯的, 雙cpu運用 是由系統分配, 除非你程式中指定cpu 在http://delphi.ktop.com.tw/board.php?cid=168&fid=923&tid=90685 有提到,但是我沒雙cpu,也沒這樣試過 ===================引 用 harpist 文 章=================== C Builder 不支援... Visual C 2005 OpenMP http://msdn2.microsoft.com/en-us/library/tt15eb9t(VS.80).aspx http://www.openmp.org/drupal/ 我答:我放棄了. ===================引 用 小傑克 文 章=================== 就我的理解在mutli-thread程式中, 就像賣電影票的窗口和外面排隊的人群, 有沒有用Synchronize() 對於系統 (os), 就像有沒有警察在維持排隊的秩序, 當你用Synchronize時, 外面人雖然排很多,但是警察(delphi)會維持秩序確保只有一排隊伍, 好處是Synchronize 由delphi底層幫你做memory control 的事,例如thread共用golbal 變數, 或是某些VCL, 壞處是ap不會去壓榨os , 而當沒用Synchronize時 , 脫序的群眾一擁而上去捶打賣票的窗口(os), 這時os 如果有辦法的話, 也許會多開兩個窗口一起賣票, 但這決定權, 是在os 上,不是ap決定的, 如果售票小姐只有一個, 同時開十個窗口(10-thread waiting) 也沒用,只是一個小姐跑來跑去而已,但至少這個小姐會很忙,不會一邊看報紙一邊吃便當一邊講手機一邊賣票 我答:可以的,用兩架飛機就有兩個小姐,見最後我答的那段 ===================引 用 小傑克 文 章=================== 我注意到你在thread 的execute 中用Synchronize(call) 而在call 這個function 中做PrimeNotifyEvent , 而PrimeNotifyEvent 中你又使用LockList , 根據說明 , LockList 是通知os 由os 來確保只有一個thread 在執行.....我不知道LockList 在多cpu機器中具體的運作是怎樣, 但我猜LockList 實現的方法還是讓Lock / unlock 期間的程式同一時間只有一個在執行 我答:我刪了Synchronize和LockList 也不行 ===================引 用 小傑克 文 章=================== 我之前貼的那個小測試程式,主要是測試 Synchronize (我有remark 起來), Application.ProcessMessages, sleep(1) 這三個,這三個對結果都是有影響的,你可以試試沒有Synchronize 沒有sleep的時候的狀況, 再加大一點cpu忙碌程度試試看(比如跑個1 - 50000萬空for loop的) 我答:連50% cpu也不到 結語:唯有將 aiThread 做成 Console 程式,外殼產生兩個 JVCL的TJvCreateProcess 控件,那個控件執行Console 程式,輸入輸出會轉到外殼. 如果三日沒有更好的解決辦法我就結案 |
RootKit
資深會員 發表:16 回覆:358 積分:419 註冊:2008-01-02 發送簡訊給我 |
|
johnlp
一般會員 發表:2 回覆:13 積分:8 註冊:2004-10-31 發送簡訊給我 |
|
bluesum
一般會員 發表:3 回覆:11 積分:2 註冊:2009-05-09 發送簡訊給我 |
===================引 用 johnlp 文 章=================== 調整thread priority [code delphi] procedure TForm1.TestduelbuttonClick(Sender: TObject); var NewThread:TAIThrd;anotherthread:TAIThrd; begin AiListBox.Clear; NewThread:=TAIThrd.Create(true); ... anotherthread.Resume; Application.ProcessMessages; sleep(500); NewThread.Priority := tpHighest; anotherthread.Priority:=tpHighest; end; [/code] 沒用 |
bluesum
一般會員 發表:3 回覆:11 積分:2 註冊:2009-05-09 發送簡訊給我 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |