C++ 多线程

C++ 多线程编程概述

在当今计算机技术飞速发展的时代,多线程已经成为提高程序运行效率的重要手段。多线程程序能够在同一时间内执行多个任务,充分利用计算机的多核处理器,提高系统的并发性能。C++ 作为一门通用编程语言,对多线程编程提供了良好的支持。本文将介绍 C++ 多线程编程的基本概念、编程模型、同步机制以及一些实际应用案例。

一、C++ 多线程基本概念


1. 线程:线程是操作系统能够进行运算调度的最小单位,它被看做是一个进程执行任务的基本单位。一个进程可以包含多个线程,共享进程的内存空间和其他系统资源。

2. 并发与并行:并发是指多个任务在同一时间段内同时执行;并行是指多个任务在同一时刻同时执行。多线程编程主要关注的是并发,但在某些情况下,通过多线程实现并行也是可能的。

3. 线程调度:操作系统负责线程的调度,根据一定的策略分配CPU时间片给各个线程。线程的调度与进程的调度类似,但线程的调度更加轻量级。

4. 线程状态:线程在其生命周期中会经历多种状态,包括新建(NEW)、就绪(RUNNABLE)、运行(RUNNING)、阻塞(BLOCKED)、等待(WAITING)、超时等待(TIMED_WAITING)和终止(TERMINATED)。

二、C++ 多线程编程模型


C++ 标准库提供了多种多线程编程模型,其中较为常用的是基于操作系统的线程(std::thread)和基于任务的线程(std::future、std::async)。下面分别介绍这两种模型。

1. 基于操作系统的线程

std::thread 类是 C++11 标准库中引入的,它封装了操作系统线程的创建、启动、同步和终止等操作。使用 std::thread 创建线程时,需要提供一个 Callable(可调用对象),如函数、 lambda 表达式等。

创建线程:

std::thread t(std::bind(function, args...));
启动线程:

t.start();
等待线程完成:

t.join();
获取线程返回值:

std::future<T> get_future(bool wait = true) {
if (wait) {
t.join();
}
return t.get();
}
2. 基于任务的线程

C++11 标准库还引入了 std::future、std::async 等功能,用于处理异步任务。基于任务的线程模型通过 std::future 和 std::async 实现,可以避免显式地操作线程,简化代码。

创建异步任务:

std::future<T> f = std::async(std::launch::deferred, function);
等待任务完成:

f.wait();
获取任务返回值:

T result = f.get();

三、C++ 多线程同步机制


在多线程环境下,为了防止多个线程同时访问共享资源导致数据不一致等问题,需要使用同步机制。C++ 标准库提供了多种同步工具,如下所示。

1. 互斥锁(std::mutex)

互斥锁用于保护共享资源,确保同一时刻只有一个线程可以访问共享资源。使用互斥锁时,需要使用 lock_guard 或其他类似对象锁定和解锁互斥锁。

std::mutex m;
m.lock();
// 访问共享资源
m.unlock();
2. 读写锁(std::read_write_mutex)

读写锁分为读锁和写锁。在读锁保护期间,其他线程只能读取共享资源;在写锁保护期间,其他线程既不能读取也不能写入共享资源。使用读写锁可以提高并发性能,特别是在读操作远多于写操作的场景下。

std::read_write_mutex rwm;
std::unique_lock<std::read_write_mutex> rlck(rwm::reader());
// 读取共享资源
3. 条件变量(std::condition_variable)

商务合作QQ:3765323427
Copyright © 2021-2024 冰狐智能辅助. All rights reserved. 浙ICP备15043866号 《冰狐智能辅助服务协议》