o 50 do begin //进入临界段 EnterCriticalSection(Critical1); for J:=1 to 20 do for K:=1 to 3000 do if letters[j]<'Z' then letters[j]:=succ(Letters[j]) else letters[j]:='A'; str:=letters;
//退出临界段 LeaveCriticalSection(Critical1);
synchronize(addtolist); end; end;
好了,重新编译,运行结果如下图所示(略) 程序成功的避免了冲突,看来真的很简单,我们成功了!当然我们还可以 使用其它同步技术如 Mutex(互斥对象), Semaphore(信号量)等,这些技术 都是 Windows 通过 API 直接提供给我们的。
下面总结一下 Windows
常用的几种线程同步技术。 1. Critical Sections(临界段),
源代码中如果有不能由两个或两个以 上线程同时执行的部分,可以用临界段来使这部分的代码执行串行化。 它只能在一个独立的进程或一个独立的应用程序中使用。 使用方法如下: //在窗体创建中 InitializeCriticalSection(Critical1) //在窗体销毁中 DeleteCriticalSection(Critical1) //在线程中 EnterCriticalSection(Critical1) ……保护的代码 LeaveCriticalSection(Critical1)
2. Mutex(互斥对象),是用于串行化访问资源的全局对象。我们首先设 置互斥对象,然后访问资源,最后释放互斥对象。在设置互斥对象时,如果另一 个线程(或进程)试图设置相同的互斥对象,该线程将会停下来,直到前一个线 程(或进程)释放该互斥对象为止。 注意它可以由不同应用
程序共享。 使用方法如下: //在窗体创建中
hMutex:=CreateMutex(nil,false,nil) //在窗体销毁中 CloseHandle(hMutex) //在线程中 WaitForSingleObject(hMutex,INFINITE) ……保护的代码 ReleaseMutex(hMutex)
3. Semaphore(信号量),它与互斥对象相似,但它可以计数。例如可以 允许一个给定资源同时同时被三个线程访问。其实 Mutex 就是最大计数为一的 Semaphore。 使用方法如下: //在窗体创建中 hSemaphore:= CreateSemaphore(nil,lInitialCount,lMaximumCount,lpName) //在窗体销毁中 CloseHandle(hSemaphore) //在线程中 W
aitForSingleObject(hSemaphore,INFINITE) ……保护的代码 ReleaseSemaphore(hSemaphore, lReleaseCount, lpPreviousCount)
4. 还可以使用
Delphi 中的 TcriticalSection 这个 VCL 对象, 它的定义在 Syncobjs.pas 中。 当你开发多线程应用时,并且多个线程同时访问一个共享资源或数据时, 你需要考虑线程同步的问题了。
delphi 中多线程同步的一些方法 [ 2006-01-09 10:48:03 | 作者: snox 字体大小:大 |中 |小 ] 当有多个线程的时候, 经常需要去同步这些线程以访问同一个数据或资源。 例如,假设有一个程序,其中一个线程用于把文件读到内存,而另一个线程用于 统计文件中的字符数。当然,在把整个文件调入内存之前,统计它的计数是没有 意义的。但是,由于每个操作都有自己的线程,操作系统会把两个线程当作是互 不相干的任务分别执行,这样就可能在没有把整个文件装入内存时统计字数。为 解决此问题,你必须使两个线程同步
工作。 存在一些线程同步地址的
问题,Win32 提供了许多线程同步的方式。在本 节你将看到使用临界区、 互斥、信号量和事件来解决线程同步的问题。
1. 临界区 临界区是一种最直接的线程同步方式。所谓临界区,就是一次只能由一个 线程来执行的一段代码。如果把初始化数组的代码放在临界区内,另一个线程在 第一个线程处理完之前是不会被执行的。 在使用临界区之前,必须使用 InitializeCriticalSection()过程来初始 化它。 其声明如下: procedure InitializeCriticalSection(var lpCriticalSection 参数是一个 TRTLCriticalSection 类型的记录, 并且是变参。至于 TRTLCriticalSection 是如何定义的,这并不重要,因为很 少需要查看这个记录中