关于线程中Synchronize()函数的调用问题!

翰墨书缘 2005-09-23 09:03:08
各位走过路过的高手帮帮忙喽~~~~~~嘿嘿!!
小弟在做串口接收数据的时候用的是多线程,其中主体的Excute中只有几句代码
while not Terminated do
begin
Synchronize(ReadPort);
end;
现在的问题是,我开了三个线程用来接收串口一、二、三上来的数据,在一个线程接收的时候我将其余的两个线程挂起(线程名.Suspend),在不断的挂起(Suspend),恢复(Resume)过程中,会出现程序死在那里的现象(本来接收线程开的时候CPU占用率达到80%以上,但是这时CPU占用率不超过5%)。这三个线程都是同一个类的不同对象。我就想问问各位高手,怎么样能避免程序死在那里?是不是由于Synchronize函数才会出现这种情况的啊?先谢谢大家了!!分不够再加~~~~
...全文
328 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
翰墨书缘 2005-09-28
  • 打赏
  • 举报
回复
var
_flag1:integer=0;
_flag2:integer=0;
BaseTime:TDatetime;

procedure TReadThread.Execute;
begin
{ Place thread code here }
_Pos:=0;
while not Terminated do
begin
Synchronize(ReadPort);
end;
end;

function TReadThread.TimeInterval(Time_S,Time_E:TDatetime):integer;
var
Hour_S,Minute_S,Second_S,MSec_S:Word;
Hour_E,Minute_E,Second_E,MSec_E:Word;
begin
if Time_S<=Time_E then
begin
decodetime(Time_S,Hour_S,Minute_S,Second_S,MSec_S);
decodetime(Time_E,Hour_E,Minute_E,Second_E,MSec_E);
Result:=(Hour_E-Hour_S)*3600000+(Minute_E-Minute_S)*60000+(Second_E-Second_S)*1000+(MSec_E-MSec_S)
end
else
begin
decodetime(Time_E,Hour_S,Minute_S,Second_S,MSec_S);
decodetime(Time_S,Hour_E,Minute_E,Second_E,MSec_E);
Result:=((Hour_E-Hour_S)*3600000+(Minute_E-Minute_S)*60000+(Second_E-Second_S)*1000+(MSec_E-MSec_S))*(-1);
end;
end;

procedure TReadThread.ReadPort;
var
inbuff:array [0..255] of char;
hcomm:Thandle;
nByteRead,dwError:longword;
cs:TComStat;
i:integer;
RecvStr:string;
begin
hcomm:=SeriesPort;
if (hcomm=0) then Exit;
ClearCommError(hcomm,dwError,@cs);
ReadFile(hcomm,inbuff,cs.cbInQue,nByteRead,nil);
//接收通信端口的数据
if cs.cbInQue=0 then
begin
if _flag1=1 then// 表示上次监听端口时串口有数据
begin
_flag1:=0;
_flag2:=1;
BaseTime:=now;//设置时间基数
end
else //此时_flag1为0 表示上次监听端口时串口无数据
begin
if _flag2=1 then
begin
if TimeInterval(BaseTime,now)>20 then//比较当前时间与时间基数的差值
begin
_flag2:=0;
//字符串结束时(即一帧接收完毕时)的动作
DataHandle(SerisePortID);//接收字符的处理函数
end;
end
else Exit;
end;
Exit;
end;
//串行在读取数据后,会自动将缓冲区中已被读取的数据清除掉
//if cs.cbInQue=0 then exit;
//数据是否大于所准备的buffer
if cs.cbInQue>sizeof(inbuff) then
begin
PurgeComm(hcomm,PURGE_RXCLEAR);//清除通信端口数据
exit;
end;
_flag1:=1;//表明收到数据了

RecvStr:='';
for i:=0 to cs.cbInQue-1 do //取出数据
begin
ReceByte[i+_Pos]:=ord(inbuff[i]);
RecvStr:=RecvStr+inttohex(ReceByte[i+_Pos],2)+' ';
end;
RunLog('R:'+RecvStr);
_Pos:=_Pos+integer(cs.cbInQue);
//如果串口中有数据的话,就将数据读出并添加到ReceByte字节数组中
//_Pos代表了接收到的字符的个数
end;

各位大侠,上面就是我串口接收线程的代码部分,之所以不断的挂起恢复线程,是因为如果三个线程一起开的话,内存的占用量相当的大,整个界面的相应就会变得很慢。看了各位的留言,我想可能是我的思路有些问题,大家有什么好的方式来解决这个问题吗?谢谢各位了~~~:)
cqwty 2005-09-26
  • 打赏
  • 举报
回复
把你的线程的完整代码贴出来,
xgbing 2005-09-26
  • 打赏
  • 举报
回复
可能也与下位机的程序有关
具体要看情况而定喽,呵呵
  • 打赏
  • 举报
回复
[小弟在做串口接收数据的时候用的是多线程,其中主体的Excute中只有几句代码
while not Terminated do
begin
Synchronize(ReadPort);
end;]

多线程的程序这么写那多线程还有意义么?
aiirii 2005-09-26
  • 打赏
  • 举报
回复
>>我开了三个线程用来接收串口一、二、三上来的数据
这种情况,应该不用挂起线程,

也不用 Synchronize
kfb007 2005-09-26
  • 打赏
  • 举报
回复
通过Synchronize(ReadPort)控制同步不需要手工实现挂起(线程名.Suspend)吧,应该是系统自动将线程排队。
xgbing 2005-09-24
  • 打赏
  • 举报
回复
定义全局变量
CRITICAL_SECTION g_cs;  //临界区

__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
InitializeCriticalSection(&g_cs);  //初始化临界区
    .....

在读数据或写数据前
EnterCriticalSection(&g_cs);//进入临界区
....
LeaveCriticalSection(&g_cs);//退出临界区

记得关闭程序前
DeleteCriticalSection(&g_cs);

Bluce4587 2005-09-24
  • 打赏
  • 举报
回复
如果你的ReadPort中也有线程的话,可能会出现这种情况
可以试试楼上的
huabihan 2005-09-23
  • 打赏
  • 举报
回复
是不是同步出现问题,还是发生死锁了?
zwm09 2005-09-23
  • 打赏
  • 举报
回复
关注

16,748

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 语言基础/算法/系统设计
社区管理员
  • 语言基础/算法/系统设计社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧