Linux下C/C++多线程编程实战指南

一、前言

在现代软件开发中,多线程已成为提高程序并发能力和响应性能的关键手段。尤其在嵌入式、网络服务、图像处理等领域,多线程编程几乎是基础能力。然而,线程引入的同步问题、资源竞争、死锁等挑战,也让多线程成为一门“易用难精”的技术。

本文将基于 Linux 环境,以 C/C++ 为语言基础,系统性讲解多线程编程的核心技术与实战经验,适合对线程有一定基础、希望深入掌握线程控制与优化的开发者。

二、线程基础与 pthread 编程模型

2.1 创建线程

Linux下多线程主要通过 POSIX Threads(pthread)库实现:

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

void* thread_func(void* arg) {
    printf("Hello from thread: %ld\n", pthread_self());
    return NULL;
}

int main() {
    pthread_t tid;
    pthread_create(&tid, NULL, thread_func, NULL);
    pthread_join(tid, NULL);
    return 0;
}

2.2 pthread 属性控制

pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setstacksize(&attr, 1024 * 1024);
pthread_create(&tid, &attr, thread_func, NULL);
pthread_attr_destroy(&attr);

三、线程同步机制

3.1 互斥锁(Mutex)

pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;

pthread_mutex_lock(&lock);
// 临界区
pthread_mutex_unlock(&lock);

C++封装:

#include <mutex>

std::mutex mtx;
std::lock_guard<std::mutex> guard(mtx);

3.2 条件变量(Condition Variable)

pthread_mutex_t lock;
pthread_cond_t cond;

pthread_cond_wait(&cond, &lock);  
pthread_cond_signal(&cond);       

3.3 读写锁(RWLock)

pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZER;

pthread_rwlock_rdlock(&rwlock); 
pthread_rwlock_wrlock(&rwlock); 

四、线程安全与资源竞争

4.1 原子操作(Atomic)

#include <atomic>

std::atomic<int> counter(0);
counter.fetch_add(1, std::memory_order_relaxed);

4.2 内存可见性与屏障

  • std::memory_order_seq_cst
  • std::memory_order_relaxed

五、线程池设计模式

5.1 简单线程池结构:

+-----------------------+
|    任务队列(队列)    |
+----------+------------+
           |
   +-------v--------+
   | 线程池中的工作线程 |
   +------------------+

5.2 核心代码(简化版):

typedef struct {
    void (*function)(void*);
    void* arg;
} task_t;

void* thread_worker(void* arg) {
    while (1) {
        pthread_mutex_lock(&mutex);
        while (queue_empty()) pthread_cond_wait(&cond, &mutex);
        task_t task = dequeue();
        pthread_mutex_unlock(&mutex);
        task.function(task.arg);
    }
}

5.3 实战建议:

  • 支持任务优先级
  • 支持动态扩容与销毁
  • 限制最大线程数

六、多线程调试与性能分析

6.1 常见问题定位

  • 死锁:使用 gdb + info threads
  • 竞争条件:使用 HelgrindThreadSanitizer

6.2 gdb 多线程调试技巧

(gdb) info threads
(gdb) thread <id>
(gdb) bt

6.3 性能优化点

  • 锁粗化或细化
  • 使用无锁数据结构
  • 合理划分任务粒度

七、C++11/17/20线程模型(进阶推荐)

#include <thread>

void foo(int x) { ... }

std::thread t1(foo, 10);
t1.join();

配合 <mutex>, <condition_variable>, <future> 等使用。

八、实战案例:日志系统中的异步写入线程

class AsyncLogger {
private:
    std::thread log_thread;
    std::queue<std::string> log_queue;
    std::mutex mtx;
    std::condition_variable cv;
    bool running = true;

    void thread_func() {
        while (running) {
            std::unique_lock<std::mutex> lock(mtx);
            cv.wait(lock, [this]{ return !log_queue.empty() || !running; });
            while (!log_queue.empty()) {
                auto msg = log_queue.front();
                log_queue.pop();
                write_to_file(msg);
            }
        }
    }

public:
    AsyncLogger() {
        log_thread = std::thread(&AsyncLogger::thread_func, this);
    }

    void log(const std::string& msg) {
        std::lock_guard<std::mutex> lock(mtx);
        log_queue.push(msg);
        cv.notify_one();
    }

    ~AsyncLogger() {
        running = false;
        cv.notify_all();
        log_thread.join();
    }
};

九、总结与建议

  • 优先考虑同步策略
  • 推荐线程池/任务系统
  • 精通调试工具

十、后记

希望本文不仅提供了技术细节,更提供了设计思维与实战经验,帮助你在多线程开发中游刃有余。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值