对于线程的二个问题,请各位高手,高手,高高手看一看!(50分)

  • 主题发起人 主题发起人 wanzhigang
  • 开始时间 开始时间
W

wanzhigang

Unregistered / Unconfirmed
GUEST, unregistred user!
1.如果我定义了一个全局变量是字节类型的,有多个线程访问它,我不用Synchronize函数可以吗。
因为我想无论怎样,系统也会吧一个字节的处理完了才会把控制权转向其它的线程吗,不可能出现
只写半个字节的情况出现吧。比如我要吧$67赋给这个全局变量,系统不会把高位的6赋给变量时控制
权就交给其它的线程了吧,应该最低也是以字节为单位进行处理的吧,不会了现半个字节的问题吧!
2.如果我要用线程在窗口上画一个波形,之中会有集样的时间,所以画波形可能需要有一定的时间,
如果我用Synchronize函数,主窗中的响应就会变得非常的迟钝,或者说根本就不响应,而我必须要
窗口必须响应。应该怎么办?
如果我保证窗口中没有与画波形冲突的代码,即不会去画同一个地方(或者说不会画同一个控件)
我是不是就可以不用Synchronize函数。
谢谢大家
 
1.如果多个线程同时都想修改它呢?如果一个线程刚改完还没达到目的,另一个线程又给
改了可不可以?
2.在线程中使用消息循环。
3.不行吧。
4.请参考 http://www.delphibbs.com/delphibbs/dispq.asp?lid=1414550
 
对于数据处理和界面处理,我是这样作的,一般没有人需要非常频繁的刷新
界面,所以需要显示的参数计算完成后,放在全局内存中,在需要的时候,可以post给主
进程一个消息更新界面,这样整体会稳定很多,在线程中刷新界面会有很多问题。
 
用inter*****互锁函数,他可以以原子的方式对变量进行操作!
 
对,应该使用原子函数。
1、虽然CPU最低以字节为单位,但是读写字节通常要分两步 char a=‘/67’;
一、读常量入寄存器 Mov AL #67 二、写变量 Mov a AL
但是通常赋值的会是变量,a=b 那就更多几步...
2、如果是想绘图,可以在内存中建立BitMap 用TBitMap或Api都可以,所有画图操作在线程内
进行,画好了再显示出去,这样就只是显示时同步就可以了(Synchronize,Message,Event...)
3、直接在窗体上画图,会(要)触发OnPaint或其他的事件什么的,可能会影响到其他的组件或运行的代码,
具体不是很了解,但是始终有点冒险。还有缺点就是:
一旦有东西遮盖了窗体,所画的图就会丢失,窗体不会重画该图,除非处理OnPaint事件,又有同步问题
 
1.有一个误会必须澄清: 线程切换时会自动保留当前所有寄存器的。所以不必考虑寄存器中的数据被修改掉。 因此我个人认为对单cpu系统来写这个字节不会造成线程冲突。
2.我对windows gdi刷新具体实现不是很了解, 不过我认为它是单步的。 即一个进程/线程在修改显示时不会允许第二个线程同时操作(理由就是windows中特地提供了GdiFlush这个api). 因此线程在画屏幕时根本无法得知当前主进程是否也正好在刷新界面(这种冲突可能性太高了), 因此修改显示必须使用synchronize。
 
TO Another_eYes:
虽然积存器的值保留了,但是变量的值有可能被下一个线程改写,所以还是要
注意同步保护。
 

参考
http://www.delphibbs.com/delphibbs/dispq.asp?lid=1407101
 
TO Another_eYes:
1、我那个例子只是说明最简单的操作都是分几步来执行的,实际运行中不可能都是这样简单的“常数赋值”的操作的
2、最好的例子就是读、修改、写操作:a ++;
mov AL a
inc AL
mov a AL
就像张无忌所说的当读入寄存器后,a还是可以被其他线程修改,然后那个线程不知道a的值变动了,继续运行inc a
不但想要的结果没出来,连其他线程修改的结果都抹掉了
3、GDI的刷新从某种情况下可以说是安全的,就像Screen这样的“真实”设备,因为一旦有人通过GetDC获得Screen的设备上下文,
如果不释放,其他人是不能再获得Screen的DC来写屏了,这是SDK原话:After painting with a common device context, the ReleaseDC function must be called to release the device context.
但是Form的DC就不一样了:Class and private device contextsdo
not have to be released. The number of device contexts is limited only by available memory.
4、还是那句话,直接写屏,如果没有响应OnPaint,一旦没覆盖就会丢失
 
第一个问题,建议你使用WIN32提供的临界区(DELPHI好象也有封装过后的对象吧)来进行同步。
 
1:用SyncObjs.TCriticalSection进入加锁,我吃过这方面的苦头,别以为光读就不会出错,
一旦出错的时候,连接什么错误你都很难找出来。如果不想用TCriticalSection,那就用
threadvar来声明,它声明的变量是线程安全的(我也说不清)
2:你用Form1.Canvas.Lock先将Canvas加锁,画完后,再Unlock就行了。同1一样的道理。
 
多人接受答案了。
 
后退
顶部