Synchronize的使用问题,在不同的计算机上使用效果不一样(Synchronize代码的详细分析,PostMessage不能通知到主线程,消息丢失) (

  • 主题发起人 yanghai0437
  • 开始时间
我不相信机器问题会导致消息丢失,如果这样,今后的软件怎么写
 
PostMessage有可能丢失,当主线程忙的时候,或者主线程被死锁时。
可能你的调用Synchronize的线程里有锁保护?
因为有锁保护,当线程执行时,主线程被锁住,所以无法收到postmessage,造成死锁
 
我自己没有加锁保护
 
//还有一个现象就是我在能够正常执行的计算机上编译后,将可执行程序复制到
兼容机上后也能够正常执行,只要在这台兼容机上编译后就不能正常执行
想不到有其他的理由,只能是可能你的DELPHI环境有一定的问题.
$IFDEF MSWINDOWS}
SyncProc.Signal := CreateEvent(nil, True, False, nil);//明明就是这里产生的
try
{$ENDIF}
 
to zjan521,
那个地方只是创建了信号量,并没有产生信号事件。
//想不到有其他的理由,只能是可能你的DELPHI环境有一定的问题.
我对比了Options中的所有参数,完全一样,我不知道还有那里需要调整,请指教
 
SyncList.Add(@SyncProc);
主线程应该会在适当的时候,比如idle检索SyncList
 
>>我对比了Options中的所有参数,完全一样,我不知道还有那里需要调整,请指教
你的两台机器上,Delphi都打过补丁没?都打到哪个版本的补丁了?Windows呢?也打过补丁吗?
 
以前我用Synchronize访问VCL组件时,是会问题,可能在某些情况下,可能是不同步。
后来用发通知消息方式解决了,postmessage发消息给主窗体方式,肯定是可行的。请检查
你的代码,(在线程里用POSTMESSAGE循环发消息不是太好,用SENDMESSAGE试试)
 
关注,帮顶!!没有灌水啊
 
我来看帖了,但这个问题我也没有接触过
不过我可以说,这个绝对不是品牌机与兼容机的区别
因我是卖电脑的
可以说,这种现象多半是由于两台电脑所装的软件不同
很可能哪个软件和它有冲突。
最多是两台电脑的配置不一样
但你不可以说,什么软件在品牌机上运行没事
但在兼容机上就运行不了。
 
正确地说,品牌机运行不了的程序在兼容机上很好运行,我不是卖电脑的,我是兼职修电脑的熟手男工,有些机就是这么怪,与主板芯片有关,有些程序与监控芯片、板载声卡芯片有关,或者它们的电路设计也有关,特别是一些设备的驱程,换了其他板则问题解决,但品牌机不能换板,所以只有兼容机才能运行,如楼上所说,不能运也与安装的系统有关。
 
谢谢大家的分析。不过我认为不会与计算机有关,应为我在可以运行的计算机上编译后,
复制到那台计算机上,照样可以运行正常。只是在不可以运行的计算机上编译后就不可以
运行了。而且分析了delphi代码,发现是postmessage函数发送的消息不能正确到达主线程,
目前我还是不清楚Postmessage在什么情况下会导致发送消息不能到达主线程。
wbtvc,说主线程忙或者锁死时不能到达,但是我的程序代码是在OnShow事件中执行的,
应该不会是主线程忙或者锁死了。因为我没有什么代码来锁死主线程
 
用SNEDMESSAGE试试呀,POSTMESSAGE跟SENDMESSAGE是有区别的。
 
建议用CriticSection和SimpleEvent代替Sychronize.
要进行同步控制,一般都是使用CriticSection. 它比Sychronize灵活得多。
参见TCriticSection的帮助。
我们WebServer, FTPServer写的时候都是用CriticSection的。Sychronize不行
 
“在可以运行的计算机上编译后,复制到那台计算机上,照样可以运行正常。只是在不可以运行的计算机上编译后就不可以运行了”
我觉得倒正说明了原因就在于系统、电脑的不同。同样的源代码,编译生成的EXE内容按理说应该是一样的(?),你可以用个文件比较工具把在两台电脑上编译生成的EXE比较一下,看看内容是否完全一致。两台电脑的CPU各是什么?CPU厂家、品牌、型号不同,也许有可能运行结果会有些差异吧。
不过还是建议用SendMessage发送消息来进行同步,说实话,我也发现Synchronize同步机制是有一定的问题的,不过是在主线程释放线程对象调用WaitFor时:
同步处理Synchroize中,WakeMainThread是PostMessage(Handle, WM_NULL, 0, 0);
而WaitFor函数中,WaitResult := MsgWaitForMultipleObjects(2, H, False, 1000, QS_SENDMESSAGE);
一个是PostMessage,一个是只会在SendMessage发送消息过来时才会返回(QS_SENDMESSAGE),这样同步处理时主线程没有给唤醒,就不能处理线程同步过程,而Synchronize也因为WaitForSingleObject(SyncProc.Signal, INFINITE)被挂起啦
 
看了一下帖子,代码是Delphi的TThread的代码,用TThread也写了不少代码,不过我很少使用Synchronize方法(Delphi的VCL好像没有几个是线程安全的),主要是消息为主,而且其实用同步感觉也违背了软件开发的原则,要减低耦合。
如果说在不同机器上效果不一样,我觉得软件的可能性大点,也就是操作系统
以上个人看法,仅供参考
 
类似的问题
http://www.delphibbs.com/delphibbs/dispq.asp?lid=3165421
 
顶部 底部