多线程编程之一——问 题 提 出
作者:韩耀旭
一、问题的提出
编 写 一个 耗 时 的 单 线程 程 序 :
新 建 一 个 基 于 对 话 框 的 应 用程 序 SingleThread, 在 主对 话 框
IDD_SINGLETHREAD_DIALOG 添 加 一 个 按 钮 ,ID 为 IDC_SLEEP_SIX_SECOND,标 题为 “延时
6 秒 ”,添加 按钮 的 响 应函 数 , 代码 如 下 :
void CSingleThreadDlg::OnSleepSixSecond()
{
Sleep(6000); //延时 6 秒
}
编 译 并 运 行 应 用 程 序 , 单 击 “延时 6 秒 ”按 钮 , 你 就 会 发 现 在 这 6 秒 期 间 程 序 就象 “死机”
一 样,不 在 响 应 其 它 消 息 。为了 更 好地 处 理 这 种 耗 时 的 操 作 ,我 们 有必 要 学 习 ——多线程编程。
二、多线程概述
进 程 和 线 程 都 是 操 作 系 统 的概 念 。 进 程 是 应 用 程 序 的执 行 实例 , 每个 进 程 是 由 私 有 的 虚
拟 地 址 空 间 、 代 码 、数 据 和 其它 各 种系 统 资 源组 成 , 进 程 在 运 行 过 程 中 创 建 的 资 源 随 着 进程
的 终 止 而 被 销 毁 , 所使 用 的 系统 资 源在 进 程 终止 时 被 释 放 或 关 闭 。
线 程 是 进 程 内 部 的 一 个 执 行单 元 。 系 统 创 建 好 进 程 后, 实 际上 就 启动 执 行 了 该 进 程 的 主
执 行 线 程 , 主 执 行 线程 以 函 数地 址 形式 , 比 如 说 main 或 WinMain 函 数 ,将 程 序 的 启 动 点 提
供给 Windows 系统。主执行线程终止了,进程也就随之终止。
每 一 个 进 程 至 少 有 一 个 主 执行 线 程 , 它 无 需 由 用 户 去主 动 创建 , 是由 系 统 自 动 创 建 的 。
用 户 根 据 需 要 在 应 用程 序 中 创建 其 它线 程 , 多个 线 程 并 发 地 运 行 于 同 一 个 进 程 中 。 一 个 进 程
中 的 所 有 线 程 都 在 该进 程 的 虚拟 地 址空 间 中 ,共 同 使 用 这 些 虚 拟 地 址 空 间 、 全 局 变 量 和 系 统
资 源 , 所 以 线 程 间 的通 讯 非 常方 便 ,多 线 程 技术 的 应 用 也 较 为 广 泛 。
多 线 程 可 以 实 现 并 行 处 理 ,避 免 了 某 项 任 务 长 时 间 占用 CPU 时 间 。 要 说 明 的 一 点 是 , 目
前 大 多 数 的 计 算 机 都是 单 处 理器( CPU)的 ,为 了 运 行 所 有这 些 线 程,操 作 系 统 为 每 个 独 立 线
程 安 排 一 些 CPU 时 间, 操 作 系 统 以 轮 换 方 式 向 线 程 提 供 时 间 片 , 这 就 给 人 一 种 假 象, 好 象 这
些 线 程 都 在 同 时 运 行。 由 此 可见 , 如果 两 个 非常 活 跃 的 线 程 为 了 抢 夺 对 CPU 的 控 制 权 , 在 线
程 切 换 时 会 消 耗 很 多 的 CPU 资 源 ,反 而 会 降 低 系 统 的 性 能。这 一 点 在多 线 程 编 程 时 应 该 注 意 。
Win32 SDK 函 数 支 持 进 行 多 线 程 的 程 序 设计 , 并 提 供 了 操 作 系 统 原 理 中 的 各 种 同 步 、 互
斥 和 临 界 区 等 操 作 。 Visual C++ 6.0 中,使用 MFC 类 库 也 实 现 了 多 线 程 的程 序 设 计 , 使 得 多
线 程 编 程 更 加 方 便 。