多线程的程序不稳定吗?

tonylk 2001-02-27 04:13:00
我有一个图象处理的程序,需要将一副bmp 图象中的一个个象素读出,经过变换后再存入另一张bmp,出于速度和可以随时中断的考虑我把这个变换的过程做在一个线程里,但是它运行的时候发现新生成的那副bmp中出现了很多白色的点,就是说这些点在运算后不知什么原因没有被画到目的bmp上,所以产生了空缺,而该函数在做成thread前的运行是正常的。。
我具体的做法是:在thread的create里将源图片的timage和目的图片的timage传给该thread,在thread的execute中读取源timage,得出结果后一个一个象素的写到目的提吗个中。。

难道这是由于多线程不稳定丢失数据的原因吗?请大虾们指教。。谢谢
...全文
652 27 打赏 收藏 转发到动态 举报
写回复
用AI写文章
27 条回复
切换为时间正序
请发表友善的回复…
发表回复
猛禽 2001-03-04
  • 打赏
  • 举报
回复
哈哈,有分怎能不要^_^
进本贴后,在我的帖子后的空格里输入分即可
tonylk 2001-03-02
  • 打赏
  • 举报
回复
总算可以了,只要在线程里操作图片前同时对两张图片的canvas调用lock,完成后再用unlock 就可以了。。
但我还是不太清楚为什么要这样做,是因为timage在自动重绘时不能读取其中的数据吗?还忘能有人告诉我。。

非常感谢 Raptor,,我怎么给你分呢??
tonylk 2001-03-02
  • 打赏
  • 举报
回复
总算可以了,只要在线程里操作图片前同时对两张图片的canvas调用lock,完成后再用unlock 就可以了。。
但我还是不太清楚为什么要这样做,是因为timage在自动重绘时不能读取其中的数据吗?还忘能有人告诉我。。

非常感谢 Raptor,,我怎么给你分呢??
猛禽 2001-03-01
  • 打赏
  • 举报
回复
在多线程中处理本来就麻烦,弄得不好是会不稳定的,最好不要用TBITMAP类嘛,或者用LOCK把CANVAS锁住可能也可以.
严黎斌 2001-02-28
  • 打赏
  • 举报
回复
正如楼上几位所说,因为性能的原因,VCL不直接支持线程,或者说是线程不安全的。
但是,可以用TThread.Synchronize来同步线程对VCL的操作。
请看下面的例子,具体请看Delphi中TThread的帮助。

This example shows how to call a button抯 click method in a thread-safe manner:

procedure TMyThread.PushTheButton;

begin
Button1.Click();
end;

procedure TMyThread.Execute;
begin
...
Synchronize(PushTheButton);
...
end;

所以,比照这个例子,你应该把画图函数独立成一个过程,然后在ConvertThread.Execute中通过Synchronize来调用。
还有,提示一下,如果你一点点甚至是一条条画图的话,速度是很慢的。建议在内存中开辟一个bitmap,画上去,然后整个复制到界面上。这样快非常之多!
BCB 2001-02-28
  • 打赏
  • 举报
回复
编一编多线程的程序可以加深对多线程的了解;
我认为:
如果各个线程之间空闲时间不多,采用多线程的办法不一定能
加快速度,由于VCL限制多线程访问,不得不用“同步”、“互斥”
的办法减少冲突,进一步降低了多线程的效率;
我的看法不知对不对?!

tonylk 2001-02-28
  • 打赏
  • 举报
回复
谁来帮帮我!!!
tonylk 2001-02-28
  • 打赏
  • 举报
回复
什么是同步模式???

我的问题用一个简单的例子来说明:
procedure ConvertThread.Execute;
var
i,j:integer;
begin
for j:=0 to Form1.Image1.Height do begin
for i:=0 to Form1.Image1.Width do begin
form1.Image2.Canvas.Pixels[i,j]:=form1.Image1.Canvas.Pixels[i,j];
end;
end;
end;


这是一个线程的execute中的内容,请各位试试,我运行的时候确实是有些点被绘成白色的空值了,
如果要设成同步模式,那该怎么设呢??

对不起,我只有这点分了,请帮帮忙吧
BCB 2001-02-28
  • 打赏
  • 举报
回复
在多线程,改成“同步”方式访问Bitmap1试试应该没问题了(请试一试),
可大队人马排队通过独木桥,有了独木桥哪还能快?
tonylk 2001-02-28
  • 打赏
  • 举报
回复
不使用多线程的方法我也试了,自己生成两个tbitmap类,然后对图片进行处理,再保存会timage,那样趋势很快,但我希望我的能够不段看到程序执行的状况,就是说能看到当前把图片处理到哪里了,所以那样做不太合适,
因此剩下的反感只有两种:
1)直接在当前form中对图片进行处理,但那样必须加上application。processmessages语句,速度实在太慢
2)用多线程的方法。。
所以我想我使用多线程的方法还是没错的吧
tonylk 2001-02-28
  • 打赏
  • 举报
回复
真不好意思。。又遇到问题了。。

Synchronize的参数好想必须是不带参数的函数,如果我写成:

procedure mythread.Execute;
var
i,j:integer;
begin
for j:=0 to Form1.Image1.Height do begin
for i:=0 to Form1.Image1.Width do begin
Synchronize(drawBitmap(i,j));//这里会出错!!!!!!!!!!
end;
end;
end;

procedure mythread.drawBitmap(x,y:integer);
begin
form1.Image2.Canvas.Pixels[x,y]:=form1.Image1.Canvas.Pixels[x,y];
end;

这样还是不对,那我该怎么办呢。。??
qkl 2001-02-28
  • 打赏
  • 举报
回复
我同意BCB(yhec@china.com)。
VCL原来的结构的确实不支持多线程,但后来它用了一个巧妙的方法实现了对多线程的支持。而且其实现的结果是,使用它的程序员在用VCL编写多线程程序时较少的使用烦琐的“同步”、“互斥”,当然VCL的原码并不阻止你的进一步研究。
严黎斌 2001-02-28
  • 打赏
  • 举报
回复
关于速度的问题:
首先,如果你的硬件(2cpu?)和操作系统(WinNT? 2000?)不是真正支持多处理器,那么,多线程整体上只会降低速度,而不会提升速度。最多,可能操作性,相应性能好一点。
对于你的程序,要提高速度,最有效的方法,是在内存中画好之后,整体复制到界面控件上。
firewing 2001-02-28
  • 打赏
  • 举报
回复
procedure ConvertThread.Execute;
var
i,j:integer;
begin
for j:=0 to Form1.Image1.Height do begin
for i:=0 to Form1.Image1.Width do begin
Synchronize(drawBitmap);
end;
end;
end;
procedure TMyThread.drawBitmap();

begin
form1.Image2.Canvas.Pixels[i,j]:=form1.Image1.Canvas.Pixels[i,j];
end;



firewing 2001-02-28
  • 打赏
  • 举报
回复
Sychronize的方法其实是样该过程回到主线程下执行,那速度当然和没写到线程里面一样啦。
你试一下把循环写到excute里面把描点的过程写到sychronize里面再试一下。因该就可以了。
tonylk 2001-02-28
  • 打赏
  • 举报
回复
我用Synchronize的方法确实可行了,不再有数据丢失的现象,可是我发现它的速度几乎和不做在线程里的一样,那样的话我不是就没有必要做成多线程的了吗?

但还是很感激一上给予帮助的各位大哥们!!很抱歉,我分不够,平分后只有一点点了。。
tonylk 2001-02-28
  • 打赏
  • 举报
回复
我用Synchronize的方法确实可行了,不再有数据丢失的现象,可是我发现它的速度几乎和不做在线程里的一样,那样的话我不是就没有必要做成多线程的了吗?

但还是很感激一上给予帮助的各位大哥们!!很抱歉,我分不够,平分后只有一点点了。。
disney 2001-02-27
  • 打赏
  • 举报
回复
一定是同步没有做好,我在线程中做过图像处理,是直接操作图像内存的
BCB 2001-02-27
  • 打赏
  • 举报
回复
多线程中会同时操作Bitmap1,这是VCL所不允许的;
但可改成API函数操作的办法试试。
BCB 2001-02-27
  • 打赏
  • 举报
回复
多线程中会同时操作Bitmap1,这是VCL所不允许的;
加载更多回复(7)

5,392

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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