Visual
Visual
Visual
Visual C++
C++
C++
C++ 利用互斥量同步线程实现文件读取进度条
本文适合中级读者
一、前言
文件读取进度条的实现可以有很多种方法 , 常用的是在读取文件的过程中
隔一定时间向对话框发送消息以控制进度条的位置 , 但是这种方法很难确定隔多
少时问发送一个消息 , 因为文件的大小是不确定的 , 时间间隔长了可能文件已经
读取完了还没有发送消息 , 而消息发送得太频繁又会影响文件读取的效率。特别
是在读取文本文件时你可能需要在每一个 ReadString() 函数之后都要发送一个
消息 , 而在一些格式比较复杂的文件读写代码中 ( 例如 dxf 文件的读取 ), 这样的读
取函数循环可能有几十处 , 在这样的代码中发送消息是很繁琐的事情。而利用线
程同步则可以很好地解决这个问题。
进程是一个可执行的程序 , 由私有虚拟地址空间 、 代码 、 数据和其他操作系
统资源 ( 如进程创建的文件 、 管道 、 同步对象等 ) 组成 。 一个应用程序可以有一
个或多个进程 , 一个进程可以有一个或多个线程 , 其中一个是主线程。
线程是操作系统分时调度分配 CPU 时问的基本实体 。 一个线程可以执行程
序的任意部分的代码 , 即使这部分代码被另一个线程并发地执行 , 一个进程的所
有线程共享它的虚拟地址空间、全局变量和操作系统资源。
创建一个新的进程必须加载代码 , 而线程要执行的代码已经被映射到进程
的地址空间 , 所以创建 、 执行线程的速度比进程更快 。 另外 , 一个进程的所有线程
共享进程的地址空间和全局变量简化了线程之间的通信 , 所以以线程为调度对象
要比以进程为调度对象效率高。但是在几个线程并行运行时 , 可能会存在线程的
同步问题。例如:两个线程同时对一个全局数组进行操作 , 线程 A 取得对该数组
的控制权对数组进行写入 , 当写入还未完成时 , 控制权又由线程 B 取得 , 线程 B 改
变了该数组的数据 , 然后线 程 A 又取得控制权进行读取 , 这样线 程 A 获取的数据可
能并不足其所需要的数据 , 这时就要用线程同步来解决这个问题。
Windows 提供了几种同步对象来实现线程的同步 , 常用的有临界区 (critical
section) 、互斥量 (mutexe) 、信号量 (semaphore) 、事件 (event) 和可等待的记时
器 (waitable timer) 等。线程主要使用两个函数将它们设为睡眠来等待内核对象
变为有信号:
DWORD WaitForSingleObject(HANDLE hObject, DWORD dwTimeOut)
DWORD WaitForMultipleOblects(DWORD cObject, LPHANDLE lpHandles)
函 数 WaitForSingleObjec t 告诉系统线程在等待由参 数 hObjec t 标识的内核
对象变为有信号。参数 dwTimeOut 告诉系统线程愿意等待多少毫秒。如果指定
的内核对象在指定时间内没有变为有信号 , 系统就会唤醒线程 , 让它继续执行 。 函
数的返回值 有 3 种 : WAIT_OBJECT_ 0 表示对象达到有信号状态 ; WAIT_TIMEOU T
评论1