Delphi:一个线程无法看到其他线程的数组
答案: 好吧,这很简单(可能我犯了这个错误,因为我需要更多的睡眠:)): 我创建了第一个线程,它创建了子线程并自行释放。因此,很自然地,某些子线程不会访问不存在的内存(在他们尝试之前 - 第一个线程尚未在内存中)。
嗨, 我正在尝试制作简单的应用程序。 我的需求是创建例如 1-3 个线程(我将其称为“第一线程”),这将创建接下来的几个线程(我将其称为“子线程”)。
我知道该怎么做,这就是我所做的:
第一个线程定义:
type
TFirstThread = class(TThread)
//
strict private
fID:cardinal; //fID = position on watki array + 1
fDoneItems:cardinal;
fItems:TSomeRecordAr;
//(...)
procedure ParseItem(var item: TSomeRecord; itemID:cardinal);
private
public
published
function GetItem(itemindex:cardinal):TSomeRecord;
procedure SetItem(itemindex: cardinal; item: TSomeRecord);
//(...)
procedure Execute; override;
end;
TSomeRecord 是:
TSomeRecord = record
str,str2:string;
lst:TStrings;
continue:boolean;
end;
子线程定义:
TSubThread = class(TThread)
public
fReady:boolean;
fID,fItemID:cardinal;
procedure Execute; override;
end;
还有第一个线程数组:
watki:array of TFirstThread;
第一个线程主体:
{ TFirstThread }
//(...)
procedure TFirstThread.ParseItem(var item:TSomeRecord; itemID:cardinal);
begin
//(...)
with TSubThread.Create(False) do begin
fID:=Self.fID;
fItemID:=itemID;
fReady:=True;
end;
end;
procedure TFirstThread.Execute;
var
i:cardinal;
begin
FreeOnTerminate:=True;
while fReady=False do
Sleep(10);
//(...)
fDoneItems := 1;
for i := 0 to High(fItems) do begin
ParseItem(fItems[i], i);
end;
//
end;
function TFirstThread.GetItem(itemindex: cardinal): TSomeRecord;
begin
result:=fItems[itemindex];
end;
procedure TFirstThread.SetItem(itemindex: cardinal; item: TSomeRecord);
begin
fItems[itemindex]:=item;
end;
子线程主体:
procedure TSubThread.Execute;
var
ftd:string;
tries:cardinal;
fItem:TSomeRecord;
begin
FreeOnTerminate:=True;
while fReady=False do
Sleep(10);
try
//(...)
fItem := watki[fID-1].GetItem(fItemID); //HERE AV <<
fItem.continue:=True;
//(...)
finally
watki[fID-1].SetItem(fItemID, fItem);
//(...)
//Free;
end;
end;
这就是它的样子在实践中: 在测试时,我仅创建 1 个第一个线程并启动它。它有 3 个项目,因此它创建了 3 个子线程。
当我在 TFirstThread 中设置断点时,我可以看到:
https://i.sstatic.net/EGaBO。 jpg
一切都好, 但之后,当我在 TSubThread 中设置断点时,这就是我得到的:
https://i.sstatic.net/ gXhHW.jpg
所以除了 fItems 之外一切都可以 - 不知道为什么,但我看不到它的内容。所以 ofc 我得到了 AV,因为我想要得到的项目不存在。
为什么会这样呢?有什么解决办法吗?
提前致谢。
顺便说一句,我正在使用 Delphi 2009
答案: 好吧,这很简单(可能我犯了这个错误,因为我需要更多的睡眠:)): 我创建了第一个线程,它创建了子线程并自行释放。因此,很自然地,某些子线程不会访问不存在的内存(在他们尝试之前 - 第一个线程尚未在内存中)。
ANSWER:
Allright, that was quite simple (probably I made this mistake coz I need more sleep :) ):
I've created First Thread and it created Sub-Threads and FREE-ed it-self. So it was naturall that some sub-thread souldn't access not existing memory (before they tryed - First Thread wasn`t already in memory).
Hi,
I'm trying to make simple application.
My needs are to create for example 1-3 threads (I will call them First Threads), which will create next few threads (I will call them Sub-Threads).
I know how to do it, this is what I have done:
First Thread definition:
type
TFirstThread = class(TThread)
//
strict private
fID:cardinal; //fID = position on watki array + 1
fDoneItems:cardinal;
fItems:TSomeRecordAr;
//(...)
procedure ParseItem(var item: TSomeRecord; itemID:cardinal);
private
public
published
function GetItem(itemindex:cardinal):TSomeRecord;
procedure SetItem(itemindex: cardinal; item: TSomeRecord);
//(...)
procedure Execute; override;
end;
TSomeRecord is:
TSomeRecord = record
str,str2:string;
lst:TStrings;
continue:boolean;
end;
Sub-Thread definition:
TSubThread = class(TThread)
public
fReady:boolean;
fID,fItemID:cardinal;
procedure Execute; override;
end;
And also array of First Threads:
watki:array of TFirstThread;
Body of First Threads:
{ TFirstThread }
//(...)
procedure TFirstThread.ParseItem(var item:TSomeRecord; itemID:cardinal);
begin
//(...)
with TSubThread.Create(False) do begin
fID:=Self.fID;
fItemID:=itemID;
fReady:=True;
end;
end;
procedure TFirstThread.Execute;
var
i:cardinal;
begin
FreeOnTerminate:=True;
while fReady=False do
Sleep(10);
//(...)
fDoneItems := 1;
for i := 0 to High(fItems) do begin
ParseItem(fItems[i], i);
end;
//
end;
function TFirstThread.GetItem(itemindex: cardinal): TSomeRecord;
begin
result:=fItems[itemindex];
end;
procedure TFirstThread.SetItem(itemindex: cardinal; item: TSomeRecord);
begin
fItems[itemindex]:=item;
end;
Body of Sub-Threads:
procedure TSubThread.Execute;
var
ftd:string;
tries:cardinal;
fItem:TSomeRecord;
begin
FreeOnTerminate:=True;
while fReady=False do
Sleep(10);
try
//(...)
fItem := watki[fID-1].GetItem(fItemID); //HERE AV <<
fItem.continue:=True;
//(...)
finally
watki[fID-1].SetItem(fItemID, fItem);
//(...)
//Free;
end;
end;
This is how doeas it looks in practice:
While I'm testing, I'm creating just 1 First Thread and start it. It has 3 items, so it creates 3 Sub-Threads.
When I make breakpoint in TFirstThread this is what I can see:
https://i.sstatic.net/EGaBO.jpg
everything is OK,
but after that when I make breakpoint in TSubThread this is what i get:
https://i.sstatic.net/gXhHW.jpg
so everithing is OK except fItems - idk why, but I can't see it's content. So ofc I get AV, coz item I want to get doesn't exist.
Why can it be like that? Any solutions?
Thanks in advance.
Btw I'm using Delphi 2009
ANSWER:
Allright, that was quite simple (probably I made this mistake coz I need more sleep :) ):
I've created First Thread and it created Sub-Threads and FREE-ed it-self. So it was naturall that some sub-thread souldn't access not existing memory (before they tryed - First Thread wasn`t already in memory).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
好吧,这很简单(可能我犯了这个错误,因为我需要更多的睡眠:)):我创建了第一个线程,它创建了子线程并自行释放。因此,很自然,某些子线程不会访问不存在的内存(在他们尝试之前 - 第一个线程尚未在内存中)。
Allright, that was quite simple (probably I made this mistake coz I need more sleep :) ): I've created First Thread and it created Sub-Threads and FREE-ed it-self. So it was naturall that some sub-thread souldn't access not existing memory (before they tryed - First Thread wasn`t already in memory).