数学建模社区-数学中国

标题: C++Builder的多线程编程中一些体会 [打印本页]

作者: 韩冰    时间: 2005-1-26 13:17
标题: C++Builder的多线程编程中一些体会
<>最近在写一个程序用到了多线程,所以对CB下的多线程有一定的学习。
' c% H2 C1 G. o" q5 N" l: I$ d现在把自己的一些心得讲一下。水平有限,写的很粗略,请大家见谅。</P>
# w2 G7 I" \# m2 i6 v4 A<>CB相对于VC来说,在CB下写多线程程序是很简单的。不仅是VCL中有TThread这个类。封装了那些关于多线程的WINDOW API。我觉得更方便的是他提供了
$ ]* A( ]' K9 s" l1 {7 ^直接访问主VCL线程中对象的能力。可以很容易的和主线程中的窗体,控件3 n  e5 C  u) C, z
打交道。和单线程的方式没有太多区别。只是在有多个线程都要访问主线程) r  {' \9 E% c& b
中的对象(比如访问同一个窗体上的StringGrid).只要用Thread的Synchronize方法来调用那段访问主VCL线程的代码(具体请看帮助),我们就不用担心访问冲突的问题了。而且对于多线程的同步和互斥,CB也对WINDOW 编程中那些机制进行了封装。比如对临界区CriticalSection封装为TCriticalSection.事件Event封装为TEvent.这些类相当简单好用。
! n5 U& ^. \' }- Z: S下面就是我觉得比较重要的几点,供大家参考.</P>8 F4 [4 I8 C& y3 c( @
<>3 O5 g& z, N* n0 o" }& R, K) B
1。TThread的WaitFor方法。是等待一个线程返回。其返回值在这个线程里可以任意设定。以便在该线程返回的时候让调用他的线程知道他的运行情况。 * j1 r$ b+ ?% [% J9 Y
  
( q- W2 W  c! o7 x在TThread的 OnTerminate事件中做线程的清除工作。他不是线程运行的一部分。 . ?% ^' |+ V* [) \! g2 ~
而是主VCL线程的一部分。所以在其中不能访问Thread的局部变量(如 int __thread i)
0 ^4 c& _, ]) L你可以把清楚代码写在这里,不用管现在在EXCUTE()方法执行到了哪个地方。 2 J  B2 j0 P$ ]7 C) I$ j+ g7 @
这么看起来有点类似于C++里的 finally 块的作用。 / |. a8 ^3 p6 d) F" i8 |/ ]
  
* O3 j/ u- e& q0 L0 t2。TEvent很重要。实现线程的同步。WaitFor(int Timeout)功能类似于
6 X$ L- `7 ~0 i3 r- O' OWINDOW API WaitforSingleObject().返回值包括: " U  r" x1 h- R" n* W( }
其中参数Timeout可以设为INFINITE表示永久等待,但这样,程序很容易死在这里。
/ y/ j) u6 S/ ]    # W$ ~" _+ p; J9 X) s8 e- n
wrSignaled 该事件发生(成功返回). 8 f6 X! `. s# @0 ^
wrTimeout 等待超时.   `, e( {1 _. w0 o  s% k
wrAbandoned 在该事件的超时期限到达前,该事件对象已经被毁灭了。. . L1 ~( L$ g: b' \0 Y- S
wrError 在等待过程中有异常产生,要知道具体产生的错误要查看 TEvent的LastError 9 ^' Z) C# f' R- m: {
属性。
" b4 F+ k/ O+ ~" s4 [7 B3 x% B" y" K  5 ^( x8 Q& B. N) S6 S; f& u4 u
3? TCriticalSection ! M  [  g: }: p; `' o) d
这个相当于WIN32编程中的临界区。
( }2 p0 H# `: |7 M5 w# [在多线程编程中,多个线程需要访问同一个公用变量的时候。 7 U8 s; X# k: S
  ' z! F, P0 R+ N! ^5 M; z- @
来保证访问的正确性。对公用变量访问的代码写在Enter();和Leave()之间。
) o) c" A, h) c, e! V比如有个公用变量 Count;
7 a, d. C6 v1 \' _: B以下代码 :
$ I' \( z1 U" E: _" ]4 _! PTCriticalSection * pSection=new TCriticalSection(); 5 {9 E$ [8 u% r; |& r; E4 B
   pSection-&gt;Enter(); # z& u) Y2 R  J5 A$ |. e
  Count++; $ {/ x" ]% y- H
   pSection-&gt;Leave();
4 c7 g" E; W+ V- V3 \6 m" U3 [# tdelete p;
0 f5 P" \8 e  L3 C& B9 z  - `; C) Q  m- t4 {9 L6 p- `
Enter()方法进入临界区,对其中的公用变量加锁。 ; H0 W. j! R6 N5 V& [% L
Leave()方法离开临界区,对其中的公用变量解锁。
( E' e1 P, o; S2 B  
( c4 f7 k: f, L' R7 O# F" K  
% H( M1 M4 m) \4.TMultiReadExclusiveWriteSynchronizer
: o5 N1 b$ Y6 X$ {6 L" j2 G用来处理类似于多个生产者和多个消费者的问题。这里的消费者是指
2 v. F; C! d/ k0 U6 W+ h+ ~/ K: M对公用变量进行读操作的线程。
* i9 k: F6 V8 S  u0 {) X% q/ A生产者是对公用变量进行写操作的线程。</P>7 }" d! y0 K) N
<>四个方法。  m& _: O0 C1 b0 @) W& [! W
  BeginRead* f! A2 R) R& [4 K3 E2 Y
  EndRead
* V4 u; |- m% u+ t2 p4 V3 w6 L& J0 {8 [这两个方法用于消费者。
9 i/ R/ X5 I7 T# r/ c) `+ [# D  BeginWrite
3 ]2 t8 |6 V$ C& V$ N  EndWrite+ ?# M% s% d! H7 ]) j$ |4 p- `* A% }% m
这两个方法用于生产者。</P>: k  J2 F2 K7 E
<>使用的时候就是要把这个TMutiReadExclusiveWriteSynchronizer 定义一个全局变量。
2 l* x5 W* r% H) g. |2 D8 h然后在其他线程中访问他。</P>, h2 b7 n/ d! |% z6 |. C
7 U7 i" g) c; l) a* t. d
<>0 T5 v5 }+ s" i
</P>
作者: zd    时间: 2005-3-24 14:27
能讲清楚点,最好用例子
作者: madio    时间: 2005-3-24 19:53
<>讲的很清楚呀!实际上就是调用TThread这个类的一些方法!在new-〉others-〉Threadobject中可以直接建立多线程对象!</P>
作者: zhuyunxiang    时间: 2005-3-28 15:00
<>最好给例子</P>
作者: dddlincool    时间: 2005-4-15 15:40
ddd
作者: dddlincool    时间: 2005-4-15 15:47
[em03]




欢迎光临 数学建模社区-数学中国 (http://www.madio.net/) Powered by Discuz! X2.5