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

請教 Thread 的問題

答題得分者是:Clarinet
frog1
一般會員


發表:25
回覆:40
積分:18
註冊:2007-01-24

發送簡訊給我
#1 引用回覆 回覆 發表時間:2007-05-23 18:11:40 IP:219.86.xxx.xxx 訂閱
Hi, 各位前輩
要貯存 每秒有30張的IPCamera JPEG圖像, 曾用IdHttp配FileStream但貯的張數不理想, 目前在試用
Timer/Thread配UrlDownLoadToFile, 但在Thread.Resume時,出現 'Thread Error控制碼無效' 的錯誤, 因對Thread大不熟,
雖爬了許久文章, 還是無法解決, 盼請各先進協助
或有其他更好的做法請指點,


下列為大部程式

--- U_GetAllPicture.Pas ----------------------
var
Form1: TForm1;
I : Integer;
implementation
Uses U_CameraThread;
{$R *.dfm}
Var MyT : CameraThread;
procedure TForm1.FormCreate(Sender: TObject);
begin
I := 1;
Timer1.Interval := 33;
MyT := CameraThread.Create(False);
end;
procedure TForm1.Timer1Timer(Sender: TObject);
Var MyT : CameraThread;
begin
I := I 1;
Myt.Resume;
end;
end.
--- U_CameraThread.Pas -------------------------------------------
implementation

Uses U_GetAllPicture;
procedure CameraThread.Execute;
begin
FreeOnTerminate := True;
Try
UrlDownLoadToFile(Nil,pchar('http://192.168.10.10/img.jpg'),Pchar('D:\AllPicture\' IntToStr(I) '.JPG'),0,nil)
Except
End;
end;
end.
Stallion
版主


發表:52
回覆:1600
積分:1995
註冊:2004-09-15

發送簡訊給我
#2 引用回覆 回覆 發表時間:2007-05-23 19:12:29 IP:211.22.xxx.xxx 未訂閱
所有的VCL都不是Thread safe的,若是你的Thread函數中含有VCL的元件或方法,應該防止Thread的重入問題;另外,如果你在Thread function中要共用變數也應該要注意Thread的重入。查一下!TRTLCriticalSection會有收穫~這有兩篇可以參考
http://delphi.ktop.com.tw/board.php?cid=31&fid=77&tid=43102

http://delphi.ktop.com.tw/board.php?cid=30&fid=69&tid=51355
===================引 用 frog1 文 章===================
Hi, 各位前輩
要貯存 每秒有30張的IPCameraJPEG圖像,曾用IdHttp配FileStream但貯的張數不理想, 目前在試用
Timer/Thread配UrlDownLoadToFile, 但在Thread.Resume時,出現 'Thread Error控制碼無效' 的錯誤, 因對Thread大不熟,
雖爬了許久文章, 還是無法解決, 盼請各先進協助
或有其他更好的做法請指點,


下列為大部程式

--- U_GetAllPicture.Pas ----------------------
var
Form1: TForm1;
I : Integer;
implementation
Uses U_CameraThread;
{$R *.dfm}
Var MyT : CameraThread;
procedure TForm1.FormCreate(Sender: TObject);
begin
I := 1;
Timer1.Interval := 33;
MyT := CameraThread.Create(False);
end;
procedure TForm1.Timer1Timer(Sender: TObject);
Var MyT : CameraThread;
begin
I := I 1;
Myt.Resume;
end;
end.
--- U_CameraThread.Pas -------------------------------------------
implementation

Uses U_GetAllPicture;
procedure CameraThread.Execute;
begin
FreeOnTerminate := True;
Try
UrlDownLoadToFile(Nil,pchar('http://192.168.10.10/img.jpg'),Pchar('D:\AllPicture\' IntToStr(I) '.JPG'),0,nil) //這個函數是Thread safe嗎?
Except
End;
end;
end.
hsgrass
一般會員


發表:1
回覆:8
積分:6
註冊:2007-05-10

發送簡訊給我
#3 引用回覆 回覆 發表時間:2007-05-24 09:21:01 IP:61.144.xxx.xxx 訂閱
Uses U_GetAllPicture;
procedure CameraThread.Execute;
begin
FreeOnTerminate := True; // 這個會在線程完成任務後自動釋放,你在它釋放後再RESUM,當然會出錯
Try
UrlDownLoadToFile(Nil,pchar('http://192.168.10.10/img.jpg'),Pchar('D:\AllPicture\' IntToStr(I) '.JPG'),0,nil)
Except
End;
end;
end.
frog1
一般會員


發表:25
回覆:40
積分:18
註冊:2007-01-24

發送簡訊給我
#4 引用回覆 回覆 發表時間:2007-05-25 09:48:37 IP:219.86.xxx.xxx 訂閱
Hi,
我把主程式中的 FreeOnTerminate := True; 拿掉
並也把 Thread 中的
UrlDownLoadToFile(Nil,pchar('http://192.168.10.10/img.jpg'),Pchar('D:\AllPicture\' IntToStr(I) '.JPG'),0,nil)
也拿掉(即Thread沒作任何事)
但在主程式上的 Myt.Resume, 還是出現 'Thread Error控制碼無效' 的錯誤
請前輩們再指點

還在研讀 Stallion 所提供的那二篇文章, 了解後我會再試
hsgrass
一般會員


發表:1
回覆:8
積分:6
註冊:2007-05-10

發送簡訊給我
#5 引用回覆 回覆 發表時間:2007-05-25 12:55:34 IP:61.144.xxx.xxx 訂閱
--- U_GetAllPicture.Pas ----------------------
var
Form1: TForm1;
I : Integer;
implementation
Uses U_CameraThread;
{$R *.dfm}
Var MyT : CameraThread;
procedure TForm1.FormCreate(Sender: TObject);
begin
I := 1;
Timer1.enabled := false;
Timer1.Interval := 33;
Timer1.enabled := true;
// MyT := CameraThread.Create(False);
end;
procedure TForm1.Timer1Timer(Sender: TObject);
Var MyT : CameraThread;
begin
I := I 1;
MyT := CameraThread.Create(False);
// resum是在当线程被SUSPEND的时候才使用的,如果线程完成任务(EXECUTE后),则RESUME可能出错
// 上次没有看仔细看你的代码
// 取文件的方式可以改进一下,请参考一些比较有名的开源代码。

end;
end.
--- U_CameraThread.Pas -------------------------------------------
implementation

Uses U_GetAllPicture;
procedure CameraThread.Execute;
begin
FreeOnTerminate := True;
Try
UrlDownLoadToFile(Nil,pchar('http://192.168.10.10/img.jpg'),Pchar('D:\AllPicture\' IntToStr(I) '.JPG'),0,nil)
Except
End;
end;
end.
frog1
一般會員


發表:25
回覆:40
積分:18
註冊:2007-01-24

發送簡訊給我
#6 引用回覆 回覆 發表時間:2007-05-25 16:17:25 IP:219.86.xxx.xxx 訂閱
Hi,
還是不行、把 MyT.Create 放在 Timer中的之前有試過、約run 2分鐘後會出現 'Thread Create Error 存放體空間不足' 、但查Windows工作管理員中的記憶體使用、並未看到異常、才會想只thread create一次、而freeonterminate=false、再一直resume引用他, 剛再試也是得到同樣結果
看了stallion 所提供的二篇文章我想、較簡單的方式是用 synchronize 測試了 10分鐘、都還沒問題、只是我下的 Timer1.Interval := 33、每分鐘應可存到1800張圖、可是實際只有 450張,
hsgrass 提到 '取檔案的方式可以改進一下,請參考一些比較有名的開來源碼' 是否就是指這個、可以再給我更好的指導嗎

編輯記錄
frog1 重新編輯於 2007-05-26 10:11:45, 註解 無‧
hsgrass
一般會員


發表:1
回覆:8
積分:6
註冊:2007-05-10

發送簡訊給我
#7 引用回覆 回覆 發表時間:2007-05-28 08:21:30 IP:61.144.xxx.xxx 訂閱
可以到DELPHIBOX搜索一下
http://www.2ccc.com/article.asp?articleid=2870
或者到
http://www.torry.net
搜索INDY,找一些文件传送的例子看看,其实INDY自带的DEMO也有文件传送的
Clarinet
高階會員


發表:9
回覆:97
積分:126
註冊:2002-05-08

發送簡訊給我
#8 引用回覆 回覆 發表時間:2007-05-28 10:41:05 IP:220.228.xxx.xxx 訂閱
Thread.Create(False)為產生一個立即執行的Thread,因此,不能再用Resume來啟動它
constructor Create(CreateSuspended: Boolean);

若你要使用Resume,應該要使用Create(True)

另,你宣告了一個 var MyT 的全域變數

而你在Timer1裡面,卻又宣告一個區域變數var MyT,而在裡面使用的MyT,應為此區域變數,但此,應該沒有被你產生(Create),因此,呼叫此,應該會產生一個記憶體錯誤!
------
GPS(全球衛星定位系統)
http://www.allgps.com
salo0610
高階會員


發表:42
回覆:120
積分:107
註冊:2003-02-18

發送簡訊給我
#9 引用回覆 回覆 發表時間:2007-05-28 13:07:34 IP:220.132.xxx.xxx 未訂閱
TThread::TThread
Creates an instance of a thread object.
__fastcall TThread(bool CreateSuspended);
Description:
Call TThread indirectly, using the new keyword, to create a thread in an application.
If CreateSuspended is false, Execute is called immediately.
If CreateSuspended is true, Execute wont be called until after Resume is called.

TThread, Priority, Resume example
This example shows how to create a thread and start it running at a lower priority than the main execution thread. It assumes that the thread FreeOnTerminate property is True, so that there is no need to free the thread when it finishes.
TMyThread *SecondProcess = new TMyThread(true); //create but dont run
SecondProcess->Priority = tpLower; // set the priority lower than normal
SecondProcess->Resume(); // now start the thread running



===================引 用 Clarinet 文 章===================
Thread.Create(False)為產生一個立即執行的Thread,因此,不能再用Resume來啟動它
constructor Create(CreateSuspended: Boolean);

若你要使用Resume,應該要使用Create(True)

另,你宣告了一個 var MyT 的全域變數

而你在Timer1裡面,卻又宣告一個區域變數var MyT,而在裡面使用的MyT,應為此區域變數,但此,應該沒有被你產生(Create),因此,呼叫此,應該會產生一個記憶體錯誤!
系統時間:2024-04-24 10:16:13
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!