比如,有一按钮,click之后用createThread生成一个线程: function test:bool; var i:integer; begin for i:=1 to 100 do begin form1.button1.caption:=inttostr(i); sleep(5); end;end; 直接将test函数的地址给createThread就可以了。 这样,就算连续按100下按钮都没事,但如果用继承类的方法就要用同步函数。
to seeking, 因为大部分VCL不是“线程安全”的,所以并行的访问会引起冲突。这与线程创建的方法无关,不管是TThread还是CreateThread都一样。 在Test中: “form1.button1.caption:=inttostr(i)”访问了VCL,如果没有同步的话,多于一个线程同时运行到这一句(仅仅是这一句,其他代码不受影响),就会引发冲突。 “就算连续按100下按钮都没事” 呵呵,这种“撞车”的概率非常小,计算一下:仅仅这一条语句的执行时间大概为:0.00002秒(实测于PIII733上,无误),100次也只需0.002秒;而你的线程总的运行时间为5*100/1000+0.00002*100=0.502秒(最小值,忽略其他代码);所以整个过程中处于“非线程安全”的敏感期只有0.4%。 任意两个运行中线程“撞车”的概率为0.4%*0.4%=0.16%;注意这是运行中的线程,考虑到你按Button1的时间损耗(实际上你也不会在0.5秒内按100次),同时运行的线程数目远远小于100。这就可以肯定地说你幸运地躲过了冲突。
在继承类 同步要比
用API两种方法做线程 方便
用类简单一些,程序结构更加清晰
线程的同步请看API函数WaitForSingleObject和WaitForMultipleObjects.
原理是在函数执行之前先等待别的线程完成,具体实现是利用信号对象等.
function test:bool;
var i:integer;
begin
for i:=1 to 100 do
begin
form1.button1.caption:=inttostr(i);
sleep(5);
end;end;
直接将test函数的地址给createThread就可以了。
这样,就算连续按100下按钮都没事,但如果用继承类的方法就要用同步函数。
因为大部分VCL不是“线程安全”的,所以并行的访问会引起冲突。这与线程创建的方法无关,不管是TThread还是CreateThread都一样。
在Test中:
“form1.button1.caption:=inttostr(i)”访问了VCL,如果没有同步的话,多于一个线程同时运行到这一句(仅仅是这一句,其他代码不受影响),就会引发冲突。
“就算连续按100下按钮都没事”
呵呵,这种“撞车”的概率非常小,计算一下:仅仅这一条语句的执行时间大概为:0.00002秒(实测于PIII733上,无误),100次也只需0.002秒;而你的线程总的运行时间为5*100/1000+0.00002*100=0.502秒(最小值,忽略其他代码);所以整个过程中处于“非线程安全”的敏感期只有0.4%。
任意两个运行中线程“撞车”的概率为0.4%*0.4%=0.16%;注意这是运行中的线程,考虑到你按Button1的时间损耗(实际上你也不会在0.5秒内按100次),同时运行的线程数目远远小于100。这就可以肯定地说你幸运地躲过了冲突。
线程总运行时间为(110/1000+0.00002)*100=11.002秒,而如果采用按键的方式去触发button1的click事件的话,每秒可生成约30个线程,则只需3至4秒就可以生成100个正在运行的线程,经测试,还未出现“撞车”。