在 Linux 下使用 C++ 进行多线程编程时,需要注意很多系统层面和语言层面的问题。下面从基础配置、线程模型、同步、性能、常见坑几个方面系统说明。
Linux 下 C++ 多线程通常基于 POSIX 线程(pthread):
g++ main.cpp -pthread -std=c++17
-pthread:同时定义宏并链接线程库(推荐,比 -lpthread 更安全)std::thread 也必须加#include <thread>
#include <mutex>
#include <condition_variable>
避免直接使用裸 pthread(除非有底层需求)。
std::thread t(func);
t.join(); // 必须 join 或 detach
⚠️ 注意:
detach 后线程资源不可控,慎用std::thread t([&](){ ... }); // 引用捕获要小心
⚠️ 如果线程比局部变量活得久,引用会悬空。
std::mutex mtx;
int cnt = 0;
void func() {
std::lock_guard<std::mutex> lock(mtx);
cnt++;
}
常见同步工具:
std::mutexstd::recursive_mutexstd::shared_mutex(C++17,读写锁)std::condition_variable死锁常见原因:
✅ 解决方案:
std::lock_guard / std::unique_lockstd::scoped_lock(C++17)std::scoped_lock lock(m1, m2);
std::condition_variable cv;
std::mutex mtx;
bool ready = false;
cv.wait(lock, []{ return ready; });
❌ 错误写法:
cv.wait(lock);
查看系统限制:
ulimit -u
cat /proc/sys/kernel/threads-max
⚠️ 线程不是越多越好:
#include <pthread.h>
cpu_set_t cpuset;
CPU_ZERO(&cpuset);
CPU_SET(0, &cpuset);
pthread_setaffinity_np(pthread_self(), sizeof(cpuset), &cpuset);
用于:
Linux 信号是进程级的:
pthread_sigmask 屏蔽❌ 不要在每个线程里 signal()
struct alignas(64) Counter {
int val;
};
适用于高频计数器。
频繁 std::thread 创建/销毁开销大。
✅ 推荐:
std::async(简单任务)gdb + info threadshtopperfhelgrind / tsan(检测数据竞争)g++ -fsanitize=thread
❌ 共享变量不加锁
❌ 线程引用局部变量
❌ join/detach 遗漏
❌ 死锁
❌ 条件变量不防虚假唤醒
❌ 线程数过多
❌ signal 使用不当
#include <thread>
#include <mutex>
std::mutex mtx;
void worker(int id) {
std::lock_guard<std::mutex> lock(mtx);
// 安全操作共享数据
}
int main() {
std::thread t1(worker, 1);
std::thread t2(worker, 2);
t1.join();
t2.join();
}
如果你愿意,我可以: