C++ 多线程支持的演进和相关 API 清单


早期 C++ 标准库没有提供多线程支持,在 C++ 上使用多线程需要借助 特定操作系统提供的 API,比如 Linux 上的 POSIX 线程库(pthread),Windows 上的 Windows API。它们提供的都是 C 语言的 API,在 C++ 上使用时通常会将其封装成类,顺便在这层封装上解决兼容性问题。C++11 正式将多线程纳入标准库,以面向对象、RAII 方式提供了 std::thread std::mutex 等一系列相关的类。

下面会依次介绍 C++11 之前 Linux 和 Windows 平台上 C 风格的多线程 API,以及 C++11 标准库提供的统一的面向对象的多线程相关类。

Linux pthread 库的多线程 API

Linux 上的 pthread 库实现了 POSIX 线程接口,提供了操作线程和 4 种锁的相关 API,是 Linux 和其他类 UNIX 系统中用于多线程编程的库。

API 清单
#include <pthread.h>

/// 线程,类型是 pthread_t,底层就是一个整型,所以参数 thread 就是一个线程 ID
pthread_create(*thread, *attr, *func) -> int        // 创建
pthread_join  (thread, void** retval) -> int        // 阻塞等待某个线程退出
// 控制线程生命周期的 API
pthread_exit  (void* retval) -> void                // 线程主动退出,类似 return
pthread_cancel(thread) -> int                       // 请求停止某个线程
/**
* pthread_cancel 可能导致内存泄漏,因为被取消的线程可能中断正在执行的任务
* 应设计线程良好地响应取消请求
* retval 是返回的错误码,不需要时直接置 NULL
*/

/// 互斥锁,类型是 pthread_mutex_t 结构体
pthread_mutex_init   (*mutex, *attr) -> int         // 创建
pthread_mutex_destroy(*mutex) -> int                // 销毁
ptrehad_mutex_lock   (*mutex) -> int                // 加锁,阻塞
pthread_mutex_trylock(*mutex) -> int                // 加锁,非阻塞
pthread_mutex_unlock (*mutex) -> int                // 解锁


/// 条件变量,类型是 pthread_cond_t 结构体
pthread_cond_init     (*cond) -> int                // 创建
pthread_cond_destroy  (*cond) -> int                // 销毁
pthread_cond_wait     (*cond, *mutex) -> int        // 等待某个条件变量,-1 操作
pthread_cond_timewait (*cond, *mutex, time) -> int  // 超时等待
pthread_cond_signal   (*cond) -> int                // 唤醒一个等待该条件变量的线程,随机唤醒,+1 操作
pthread_cond_broadcast(*cond) -> int                // 唤醒所有等待该条件变量的线程,+1 操作
/**
* pthread_mutex_t 结构体内部结构依赖于操作系统或库的具体实现,
* 对外部用户而言,它是一个不透明的类型,意味着你不需要知道其内部结构,只需通过提供的API来操作它
* 条件变量需要一个锁来保护,以确保 wait 和 signal 操作的原子性
*/

/// 读写锁,类型是 pthread_rwlock_t 结构体
pthread_rwlock_init     (*rwlock, *attr) -> int     //
pthread_rwlock_destroy  (*rwlock) -> int
pthread_rwlock_rdlock   (*rwlock) -> int            // 加读锁
pthread_rwlock_tryrdlock(*rwlock) -> int
pthread_rwlock_wrlock   (*rwlock) -> int            // 加写锁
pthread_rwlock_trywrlock(*rwlock) -> int
pthread_rwlock_unlock   (*rwlock) -> int
/**
* 读共享,写独占
*/

/// 自旋锁,类型是 pthread_spinlock_t 结构体
pthread_spin_init   (*spinlock, int);
pthread_spin_destroy(*spinlock);
pthread_spin_lock   (*spinlock);
pthread_spin_trylock(*spinlock);
pthread_spin_unlock (*spinlock);

demo

一个简单 demo,创建多线程打印线程 ID。

/* MultiThreadExample.cpp */

#include <pthread.h>
#include <stdio.h>

void *threadFunction(void *arg) {
    pthread_t tid = pthread_self();
    printf("Thread ID: %lu\n", tid);
    return NULL;
}

int main() {
    pthread_t thread1, thread2;

    pthread_create(&thread1, NULL, threadFunction, NULL);
    pthread_create(&thread2, NULL, threadFunction, NULL);

    pthread_join(thread1, NULL);
    pthread_join(thread2, NULL);

    return 0;
}

pthread 库是第三方提供,非标准库内置。所以源码用了它,则链接时需要手动链接上 pthread 库。
命令行编译的话,

g++ MultiThreadExample.cpp -lpthread -o MultiThreadExample

如果使用 CMake,则:

add_executable(MultiThreadExample MultiThreadExample.cpp)

# 链接pthreads库
find_package(Threads REQUIRED)
target_link_libraries(MultiThreadExample ${CMAKE_THREAD_LIBS_INIT})

或者直接写出库名,下面的方式和上面方式等价:

add_executable(MultiThreadExample MultiThreadExample.cpp)

# 链接pthreads库
target_link_libraries(MultiThreadExample pthread)

Windows API 提供的多线程 API

API 清单
#include <windows.h>

/// 线程
CreateThread() -> HANDLE
ExitThread()
CloseHandle()

GetCurrentThread()          // 获取当前线程的句柄
GetCurrentThreadId()        // 获取当前线程的 ID


/// 互斥锁
CreateMutex()
ReleaseMutex()
OpenMutex()

/// 条件变量

/// 读写锁

/// 自旋锁

/// 事件机制
CreateEvent()
SetEvent()
ResetEvent()
WaitForSingleObject()
WaitForMultipleObject()


C++11 标准库提供的线程库 Thread

自C++11标准起,多线程编程正式成为C++语言的一部分。标准库新增了 <thread>、<mutex>、<atomic>、<future> 等头文件,为开发者提供了统一、高效且易于使用的多线程编程工具集。

API

/// 线程,std::thread 类
#include <thread>

std::thread::thread(func, args...)      // 构造函数,创建并启动一个线程
std::thread::join()
std::thread::detach()


/// 互斥锁,std::mutex 类
#include <mutex>

std::mutex
std::lock_guard                         // RAII 类,自动管理锁的生命周期
std::unique_lock


/// 条件变量,std::condition_variable 类
#include <condition_variable>

std::condition_variable
std::recursive_mutex

/// 原子类型,std::atomic 类
#include <atomic>

demo

用 C++11 的 API 复现之前的 demo

#include <iostream>
#include <thread>
#include <string>

// 线程执行的函数
void print_thread_id(const std::string& thread_name) {
    std::cout << thread_name << " Thread ID: " << std::this_thread::get_id() << std::endl;
}

int main() {
    // 创建并启动两个线程
    std::thread thread1(print_thread_id, "Thread 1");
    std::thread thread2(print_thread_id, "Thread 2");

    // 等待两个线程完成
    thread1.join();
    thread2.join();

    std::cout << "Both threads have finished execution." << std::endl;

    return 0;
}

注意,编译时依然要显式链接上 pthread 库,因为 C++11 的 std::thread 本质上就是对操作系统提供的多线程 API 做了封装,所以在 Linux 上依然依赖 pthread 库。

add_executable(MultiThreadExample_C11 MultiThreadExample_C11.cpp)
target_link_libraries(MultiThreadExample_C11 pthread)
  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值