精通 C++ 多线程编程:高效并发开发实战
多线程基础
多线程是多任务处理的一种专门形式。多任务允许计算机同时运行两个或更多程序,分为两类:
- 进程级多任务:管理多个程序的并发执行。
- 线程级多任务:管理同一程序内多个部分的并发执行。
多线程程序包含两个或更多可并发运行的部分,每个部分称为一个线程,定义了独立的执行路径。
C++ 标准库(C++11 前)无内置多线程支持,完全依赖操作系统提供该功能。本文基于 Linux 环境,使用 POSIX 线程库(Pthreads),该 API 广泛适用于 FreeBSD、NetBSD、GNU/Linux、macOS、Solaris 等类 UNIX 系统。
创建线程
使用 pthread_create() 创建 POSIX 线程:
#include <pthread.h>
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine)(void *), void *arg);
参数说明:
| 序号 | 参数与说明 |
|---|---|
| 1 | thread:输出参数,返回新线程的唯一标识符。 |
| 2 | attr:线程属性对象,传 NULL 使用默认属性。 |
| 3 | start_routine:线程启动后执行的 C++ 函数入口。 |
| 4 | arg:传递给启动函数的单一参数,需以 void* 形式传递。 |
进程可创建的最大线程数取决于实现。线程创建后地位平等,可相互创建,无层级依赖关系。
终止线程
使用 pthread_exit() 显式退出线程:
#include <pthread.h>
void pthread_exit(void *status);
通常在线程完成工作后调用。若 main() 先于其创建的线程结束,且调用 pthread_exit(),其他线程将继续执行;否则随 main() 结束而自动终止。
示例:创建 5 个线程
#include <iostream>
#include <cstdlib>
#include <pthread.h>
using namespace std;
#define NUM_THREADS 5
void *PrintHello(void *threadid) {
long tid = (long)threadid;
cout << "Hello World! Thread ID, " << tid << endl;
pthread_exit(NULL);
}
int main() {
pthread_t threads[NUM_THREADS];
int rc, i;
for (i = 0; i < NUM_THREADS; i++) {
cout << "main() : creating thread, " << i << endl;
rc = pthread_create(&threads[i], NULL, PrintHello, (void *)i);
if (rc) {
cout << "Error: unable to create thread, " << rc << endl;
exit(-1);
}
}
pthread_exit(NULL);
}
编译命令:g++ test.cpp -lpthread(或 gcc test.cpp -lpthread)
输出示例(线程执行顺序不定):
main() : creating thread, 0
main() : creating thread, 1
main() : creating thread, 2
main() : creating thread, 3
main() : creating thread, 4
Hello World! Thread ID, 0
Hello World! Thread ID, 1
Hello World! Thread ID, 2
Hello World! Thread ID, 3
Hello World! Thread ID, 4
向线程传递参数
通过结构体传递多参数,利用 void* 的通用性:
#include <iostream>
#include <cstdlib>
#include <pthread.h>
using namespace std;
#define NUM_THREADS 5
struct thread_data {
int thread_id;
char *message;
};
void *PrintHello(void *threadarg) {
struct thread_data *my_data = (struct thread_data *)threadarg;
cout << "Thread ID : " << my_data->thread_id;
cout << " Message : " << my_data->message << endl;
pthread_exit(NULL);
}
int main() {
pthread_t threads[NUM_THREADS];
struct thread_data td[NUM_THREADS];
int rc, i;
for (i = 0; i < NUM_THREADS; i++) {
cout << "main() : creating thread, " << i << endl;
td[i].thread_id = i;
td[i].message = "This is message";
rc = pthread_create(&threads[i], NULL, PrintHello, (void *)&td[i]);
if (rc) {
cout << "Error: unable to create thread, " << rc << endl;
exit(-1);
}
}
pthread_exit(NULL);
}
线程连接与分离
两个核心函数:
pthread_join(threadid, status) // 阻塞等待线程结束
pthread_detach(threadid) // 标记为分离状态,资源自动回收
pthread_join() 会阻塞调用线程直到目标线程终止。线程创建时可指定为可连接或分离状态,仅可连接线程可被 join,分离线程不可连接。
示例:使用 join 等待线程完成
#include <iostream>
#include <cstdlib>
#include <pthread.h>
#include <unistd.h>
using namespace std;
#define NUM_THREADS 5
void *wait(void *t) {
long tid = (long)t;
sleep(1);
cout << "Sleeping in thread " << endl;
cout << "Thread with id : " << tid << " ...exiting " << endl;
pthread_exit(NULL);
}
int main() {
int rc, i;
pthread_t threads[NUM_THREADS];
pthread_attr_t attr;
void *status;
// 初始化属性并设置为可连接
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
for (i = 0; i < NUM_THREADS; i++) {
cout << "main() : creating thread, " << i << endl;
rc = pthread_create(&threads[i], &attr, wait, (void *)i);
if (rc) {
cout << "Error: unable to create thread, " << rc << endl;
exit(-1);
}
}
pthread_attr_destroy(&attr); // 释放属性对象
for (i = 0; i < NUM_THREADS; i++) {
rc = pthread_join(threads[i], &status);
if (rc) {
cout << "Error: unable to join, " << rc << endl;
exit(-1);
}
cout << "Main: completed thread id :" << i;
cout << " exiting with status :" << status << endl;
}
cout << "Main: program exiting." << endl;
pthread_exit(NULL);
}
现代 C++ 建议
C++11 起标准库提供 <thread>、<mutex>、<condition_variable> 等跨平台多线程设施,推荐优先使用标准库以提高可移植性与安全性。Pthreads 适用于遗留代码维护或需精细控制 POSIX 特性的场景。
C语言
- 机械图纸螺纹标注国家标准全解析:普通/管/梯形/锯齿螺纹
- 掌握 C++ 运算符:六大类型全解析与实战示例
- C++ 注释最佳实践:编写可读、可维护代码的注释艺术
- C++ 类模板实战指南:编写灵活的类型无关代码
- C++编程语言:核心特性全景解析
- C++常量与字面量完全手册:类型、语法与最佳实践
- C++运算符大全:算术/关系/逻辑/位/赋值/杂项与优先级结合性
- C++数值类型实战指南:基本类型、数学函数与随机数生成
- C++引用详解:核心概念、与指针三大差异及函数参数/返回值应用
- C++模板编程指南:泛型编程基石与函数/类模板实战
- 精通 C++ 多线程编程:高效并发开发实战
- C# 多线程编程精通:提升性能与效率的核心技术