张秀德 姜新通 张冬生
摘要 由于在Delphi环境中没有提供通讯控件,本文介绍了用Delphi4.0实现的Win32环境下基于线程的串行通讯程序设计,能适当降低数据丢失率以及提高系统可靠性,并给出了一个通讯
程序实例。
关键词 串行通讯 多线程
程序设计
在自动化工业控制应用中,经常需要
计算机与外围设备进行数据通讯。而异步串行通讯是一种常用的通讯手段。在单任务操作系统中,不能同时处理两件以上不同的任务。Win32是基于线程的多任务操作系统,使得应用
程序能同时执行多个任务,即在一个进程中可同时运行多个线程。利用Win32的这个特点,在通讯过程中可以适当降低数据丢失率,提高系统可靠性。
随着Win95系统的逐步普及,程序员们更愿意在Win95下编程。而Delphi也越来越为广大程序员所喜爱。然而,令人遗憾的是在Delphi环境中没有象其它的一些编程语言一样提供标准通讯控件。因此,利用Delphi进行通讯
程序设计时,不但要掌握多线程编程技术,还要了解一些与通讯相关的API函数的使用。
一 多线程基本概念
首先介绍进程概念。一个进程通常定义为
程序的一个实例。在Win32中,进程占据4GB地址空间。实际上,一个进程可以包含几个线程,它们可以同时执行进程的地址空间中的代码。为了运行所有这些线程,操作系统以轮转方式为每个独立线程分配一些CPU时间片。这给人一种假象,好像这些线程是在同时运行。创建一个Win32进程时,它的第一个线程称为主线程,由系统自动生成。然后可由主线程生成其它的线程,这些线程又可生成更多的线程。
线程描述了进程内的执行,是组成进程的基本单位。每次初始化一个进程时,系统创建一个主线程。通常对于许多应用程序,主线程是应用
程序的唯一线程。但是,进程也可以创建额外的线程,目的在于尽可能充分合理的利用CPU时间。线程可以使用CreateThread()函数来创建。
在有若干线程并行运行的环境里,同步各不同线程活动的能力是非常重要的,这样可以避免对共享资源的访问冲突。事件对象是同步线程的最基本形式,它用以向其它线程发信号以表示某一操作已经完成。例如,一个进程可能运行了两个线程。第一个线程从文件读数据到内存缓冲区中。每当数据已被读入,第一个线程就发信号给第二个线程它可以处理数据了。当第二个线程完成了对数据的处理时,它可能需要再次给第一个线程发信号以让第一个线程能够从文件中读入下一块数据。事件可以使用CreateEvent()函数来创建。线程和事件在任何时候都处于两种状态之一:有信号和无信号。当线程被创建和正在运行时,它是无信号的。一旦线程终止,它就变成有信号的。线程可以通过使用SetEvent()和ResetEvent()函数来将事件置成有信号和无信号。
除了以上介绍的概念和函数,在通讯
程序中还要用到等待函数WaitForSingleObject()和重叠I/O操作。等待函数能使线程阻塞自身执行,而重叠I/O操作能使费时的操作在后台中运行。
二 通讯
程序设计
在Windows环境下,对于串行通讯的控制是通过中断机制驱动的,由系统自行处理。Windows禁止应用程序直接和硬件打交道,程序员只能使用Windows提供的标准函数通过通讯驱动程序与硬件接口。首先,用CreateFile()函数打开通讯端口,然后通过SetupComm() 函数给通讯的输入输出队列分配一定大小的内存缓冲区,接着通过BuildCommDCB()函数 和SetCommState()等函数对主要通讯参数进行设置。初始化完成后就可以利用ReadFile()函数和 WriteFile() 函数对通讯端口进行读写操作了。
程序界面如图所示。
本文提供的实例
程序使用简单方便。利用一条串行数据线连接在两台
计算机Com2之间就可以进行文本文件传输。对于Delphi的具体编程方法这里不再赘述。实例中有详细注释。
un