projiect d:/ltest.exe faultd with message:'access violation at 0x004f3612:read o

L

lcl_003

Unregistered / Unconfirmed
GUEST, unregistred user!
projiect d:/ltest.exe faultd with message:'access violation at 0x004f3612:read of address 0x00001524.'process stopped.use step or run to continue.是什错误(50分)<br />我在线程里的一段代码出现了上面的错误,如果运行可执行文件就突然退出,如果编译就
出上面的错误,是啥意思?
 
最好把代码帖出来。
 
unit ThreadUnit2;
interface
uses
Classes,sysutils,mmsystem;
type
MyThread = class(TThread)
private
{ Private declarations }
protected
procedure Execute;
override;
end;

implementation
uses Unit1, MainForm, chartviewform, chartform, runselectform;

procedure MyThread.Execute;
var
i:byte;
//chartview:array of Tchartview;
begin
freeOnTerminate := true;
setlength(send40,10);
setlength(recv40,5400);
while( not terminated)do
//我这里是个死循环。第一次执行没有问题,第二次到这里就报那个错误
begin
send40[0]:=3;
send40[1]:=0;
send40[2]:=40;
SendData(lsn[2],send40);
RecvData(lsn[2],recv40);
if (recv40[2]=40) and (recv40[3]=1) then
for i:=0 to high(chartview1)do
begin
if chartview1<>nil then
//这是一个窗体的多实例
chartview1.Timer1.Enabled:=true;
end;
{加载就绪请求启动时钟*******} //都是指一时钟
if recv40[173]=1 then
begin
send40[0]:=5;
send40[1]:=0;
send40[2]:=37;
send40[3]:=1;
send40[4]:=1;
SendData(lsn[2],send40);
RecvData(lsn[2],recv40);
if comflag40=21 then
senddata21;
end;

{动踏步降频请求}
if recv40[173]=2 then
begin
send40[0]:=5;
send40[1]:=0;
send40[2]:=37;
send40[3]:=1;
send40[4]:=2;
SendData(lsn[2],send40);
RecvData(lsn[2],recv40);
end;

{静力实验保持时间到请求加载下一谱段******}
if recv40[173]=4 then
begin
send40[0]:=5;
send40[1]:=0;
send40[2]:=37;
send40[3]:=1;
send40[4]:=4;
SendData(lsn[2],send40);
RecvData(lsn[2],recv40);
end;

{静踏步保持?}
if recv40[173]=6 then
begin
send40[0]:=5;
send40[1]:=0;
send40[2]:=31;
send40[3]:=1;
send40[4]:=1;
SendData(lsn[2],send40);
// RecvData(lsn[2],recv40);
end;

{静踏步卸载}
if recv40[173]=8 then
begin
send40[0]:=5;
send40[1]:=0;
send40[2]:=30;
send40[3]:=1;
send40[4]:=0;
SendData(lsn[2],send40);
RecvData(lsn[2],recv40);
end;

{卸载启动时钟*******}
if recv40[173]=9 then
begin
send40[0]:=5;
send40[1]:=0;
send40[2]:=37;
send40[3]:=1;
send40[4]:=5;
SendData(lsn[2],send40);
RecvData(lsn[2],recv40);
end;

{卸载完成***********}
if recv40[170] = 4 then
begin
i:=1;
saveend(i);
end;
sleep(200);
end;

end;

end.
 
[red]for i:=0 to high(chartview1)do
begin
if chartview1<>nil then
//这是一个窗体的多实例
chartview1.Timer1.Enabled:=true;
end;
{加载就绪请求启动时钟*******} //都是指一时钟[/red]
这儿应当设置同步语句,以与你调用的form中的资源实现同步,另外在线程中用支的数据
好象也有此问题。
 
windbell, 我知道访问vcl要用同步,但是我以前没用也可以(我只是启动timer,没干别的)
如果加同步我要怎么加?
》》另外在线程中用支的数据好象也有此问题。
啥意思
 
同步很简单,用Synchronize()就可以了。
在过程开始处设一个断点,单步调试,看是在哪一步出的问题。
 
zw84611, 我知道用Synchronize,但是加在那里?
Synchronize(chartview1.Timer1.Enabled:=true;)?我不会:(
 
另外看看,两动态数组使用时有没有越界!!
setlength(send40,10);
setlength(recv40,5400);
 
Synchronize,给你个例子看一下就明白了。
TConvertThread=class(TThread)
private
Index: integer;
protected
procedure Execute;
override;
Procedure Convert;
Procedure ShowFinish;
end;
...
procedure TConvertThread.Convert;
begin
with MainFormdo
begin
CurFileName := FileNameList.Strings[index];
WebBrowser1.Navigate(CurFileName);
end;
end;

procedure TConvertThread.ShowFinish;
begin
ShowMessage('Convert has finished.');
end;

procedure TConvertThread.Execute;
var
i: integer;
begin
for i:=1 to FileNameList.Countdo
begin
Index := i-1;
ReSetEvent(FinishEvent);
Synchronize(Convert);
WaitForSingleObject(FinishEvent,5000{INFINITE});
end;
Synchronize(ShowFinish);
end;
 
我知道同步的用法,但是就是不知道怎么访问一个控件的属性和方法
比如我要访问窗体里的timer该怎么做?
我估计不是同步的事情,因为我以前访问timer没问题。因为我只是让timer.enable:=true;
没干别的
 
>>我知道同步的用法,但是就是不知道怎么访问一个控件的属性和方法
with Form1do
begin
timer1.enabled := false;
...
end;
 
zw84611, 我是说我知道在线程里的同步的用法,但是在线程里访问控件的属性和方法不知道。
不在线程里访问我还是 知道的。多谢
with Form1do
begin
timer1.enabled := false;
...
end;

 
faint,是一样的。你仔细看一下我举的那个例子。
 
在线程中实现访问外部form中的控件时必须要进行同步控制,实现同步时,要将同步的语句
作为一个函数进行,也就是说将访问控件的代码另外拿出写成一个函数,然后用同步语句进行
同步调用。就象zw84611写的代码中同步语句一样,将要同步的语句showmessage另外做成了一个
函数再在线程中调用。
 
哦,收到收到,明白。还有个疑问
1,我经过实验发现好象在线程里要同步的函数必须是线程
自己的函数吧?
2,别的单元可以访问线程里的函数吗?(我试了,好象不可以哦)
 
>我经过实验发现好象在线程里要同步的函数必须是线程
> 自己的函数吧?

>别的单元可以访问线程里的函数吗?(我试了,好象不可以哦)
没试过,你可以试试,申明一个全局的线程变量,调用其中的public类型的变量或函数。
 
zw84611, windbell, 问题已经解决了,多谢两位帮助。
>别的单元可以访问线程里的函数吗?(我试了,好象不可以哦)
我试了,不可以,不知道有没有别的办法可以解决。另外比较纳闷,因为我以前没有用一个
窗体的多实例的时候,没用同步也一点问题没有,我原来这里
if (recv40[2]=40) and (recv40[3]=1) then
for i:=0 to high(chartview1)do
begin
if chartview1<>nil then
//这是一个窗体的多实例
chartview1.Timer1.Enabled:=true;
end;

是这样写的
if (recv40[2]=40) and (recv40[3]=1) then
if chartview1<>nil then

chartview1.Timer1.Enabled:=true;
end;
一点问题也没有,我以为只是启动一个timer而已。看来以后访问vcl都要加同步才好:)
看看谁有合理的解释?
解释合理就散分
 
没人给说说?
 
这个是不用解释的,因为objectPascal语言本身就是“线程不安全的”,这就决定了delphi中
应用线程时必须考虑同步问题和资源共享的控制问题。
[red] if (recv40[2]=40) and (recv40[3]=1) then
if chartview1<>nil then

chartview1.Timer1.Enabled:=true;
end;
[/red]
->一点问题也没有
虽然没有出现问题,但却存在很大的隐患,如果在本线程外同时又有程序访问该定时器中,
这时肯定是要出问题的。所以delphi自己带的示例中,都使用了同步语句来进行控制。
 
也就说“线程不安全的”只是说”不安全“,并不说明一定会出问题,但是存在隐患?
我的理解对否?
[red] if (recv40[2]=40) and (recv40[3]=1) then
if chartview1<>nil then

chartview1.Timer1.Enabled:=true;
end;
[/red]
我这样写虽然暂时没问题,可以编译运行但是存在隐患,对吧?
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
D
回复
0
查看
1K
DelphiTeacher的专栏
D
I
回复
0
查看
617
import
I
顶部