是这样子的.最近在写多线程,实现一个串口控制一个大屏,即一个线程控制一个大屏,但是在程序写完,调试后,发现会出现本该在1#屏上显示的,在2#屏上显示,而该显示的却没有显示,而且有时好象是这么多线程只有一个在控制.贴点代码,望大家帮我看看.ds 和 execute内部的变量定义为类变量.procedure TForm1.FormShow(Sender: TObject);
var
Reg : TRegistry;
server, zh, mm : string;
q : tmysql;
begin
Reg := TRegistry.Create;
Reg.RootKey := HKEY_LOCAL_MACHINE;
if Reg.OpenKey('\SOFTWARE\tenlat\ECNALABCI\data', false) then
begin
server := Reg.readString('server');
zh := Reg.readString('zh');
mm := Reg.readString('mm');
Reg.CloseKey;
Reg.Free;
end;
if myfrm.Linkserver(server, zh, mm) = false then
begin
showmessage('不能连接数据库!!!');
close;
end;
q := tmysql.Create(1);
q.sql_str('select * from Screen_display');
disp_str := q.GetField('disp_str');
delay_time := q.GetField('delay_time');
disp_baud := q.GetField('disp_baud');
q.DestroySelf;
disp_thread_one := TDisp_thread.create(2, '2', '1');
//sleep(1000);
disp_thread_two := TDisp_thread.create(3, '3', '2');
//disp_thread_three := TDisp_thread.create(4, '4', '3');
//disp_thread_four := TDisp_thread.create(5, '5', '4');
end;
constructor TDisp_thread.create(com_para_no : integer; ado_conn_no, disp_no: string);
begin
inherited Create(true);
FreeOnTerminate := True;
CoInitialize(nil);
ds := TSendToLedOCX.Create(nil);
thread_ado_conn_no := ado_conn_no;
thread_disp_str := disp_str;
thread_delay_time := delay_time;
fScreenNostr := disp_no;
fColor := 2;
fFontLibNo := 255;
try
ds.SetComm(0, com_para_no, disp_baud, '0');
except
Synchronize(thread_setup);
Terminate;
end;
synchronize(ClearScr);
sleep(1000);
synchronize(DispSleepStr);
sleep(1000);
Resume;
end;
procedure TDisp_thread.Execute;
var
i : integer;
begin
while not terminated do
begin
synchronize(IsCheckRateDisp);
synchronize(SetDispStr);
if IDCount > 0 then
begin
if count = 0 then
begin
synchronize(NoRecord); //我目前的测试较简单,只让这块显示
sleep(strtoint(thread_delay_time));
synchronize(DispSleepStr); //我目前的测试较简单,只让这块显示
sleep(1000);
end //测试时暂时不执行else下面的程序
else
begin
end;
end;
end;
end;
var
Reg : TRegistry;
server, zh, mm : string;
q : tmysql;
begin
Reg := TRegistry.Create;
Reg.RootKey := HKEY_LOCAL_MACHINE;
if Reg.OpenKey('\SOFTWARE\tenlat\ECNALABCI\data', false) then
begin
server := Reg.readString('server');
zh := Reg.readString('zh');
mm := Reg.readString('mm');
Reg.CloseKey;
Reg.Free;
end;
if myfrm.Linkserver(server, zh, mm) = false then
begin
showmessage('不能连接数据库!!!');
close;
end;
q := tmysql.Create(1);
q.sql_str('select * from Screen_display');
disp_str := q.GetField('disp_str');
delay_time := q.GetField('delay_time');
disp_baud := q.GetField('disp_baud');
q.DestroySelf;
disp_thread_one := TDisp_thread.create(2, '2', '1');
//sleep(1000);
disp_thread_two := TDisp_thread.create(3, '3', '2');
//disp_thread_three := TDisp_thread.create(4, '4', '3');
//disp_thread_four := TDisp_thread.create(5, '5', '4');
end;
constructor TDisp_thread.create(com_para_no : integer; ado_conn_no, disp_no: string);
begin
inherited Create(true);
FreeOnTerminate := True;
CoInitialize(nil);
ds := TSendToLedOCX.Create(nil);
thread_ado_conn_no := ado_conn_no;
thread_disp_str := disp_str;
thread_delay_time := delay_time;
fScreenNostr := disp_no;
fColor := 2;
fFontLibNo := 255;
try
ds.SetComm(0, com_para_no, disp_baud, '0');
except
Synchronize(thread_setup);
Terminate;
end;
synchronize(ClearScr);
sleep(1000);
synchronize(DispSleepStr);
sleep(1000);
Resume;
end;
procedure TDisp_thread.Execute;
var
i : integer;
begin
while not terminated do
begin
synchronize(IsCheckRateDisp);
synchronize(SetDispStr);
if IDCount > 0 then
begin
if count = 0 then
begin
synchronize(NoRecord); //我目前的测试较简单,只让这块显示
sleep(strtoint(thread_delay_time));
synchronize(DispSleepStr); //我目前的测试较简单,只让这块显示
sleep(1000);
end //测试时暂时不执行else下面的程序
else
begin
end;
end;
end;
end;
>>synchronize(SetDispStr);synchronize执行的函数不是在线程中执行的,而是在主线程中执行的,检查一下这两个函数,有没有修改一些全局变量之类的东西;>>发现会出现本该在1#屏上显示的,在2#屏上显示,而该显示的却没有显示会不会是,线程1影响了在2#显示的内容;比如,假设你是从数据库中读取数据然后显示在显示屏上,那会不会,线程1移动了当前记录的位置,而导致让2#显示了别的记录的内容;
ds := TSendToLedOCX.Create(nil);那确实是不应该一个线程影响到别的线程中的ds,这个控件;
但显示了不该显示的数据,想来还是觉得,某一块各线程都会用到的数据,被修改了.建议楼主,好好考虑+好好检查代码,再仔细地测试我个人倒的觉得,楼上的synchronize用得太多了