当前位置: 首页 > article >正文

C++线程、并发、并行

 【欢迎关注编码小哥,学习更多实用的编程方法和技巧】

一、线程、并发和并行的概念

1、线程定义:

  • 程序执行的最小单元
  • 轻量级的进程
  • 共享同一进程的内存空间

特征:

  • 独立的执行路径
  • 共享进程资源
  • 上下文切换开销较小

类型:

    用户线程

    内核线程

    协程

2、并发定义:

  • 多个任务在同一时间段内交替执行
  • 宏观同时进行,微观交替

特点:

  • 单核CPU也可实现
  • 通过时间片轮转
  • 提高系统响应性
  • 资源利用率提升

实现方式:

    进程间并发

    线程间并发

    协程并发

3、并行定义:

  • 多个任务同时执行
  • 物理上同时运行

特点:

  • 多核/多处理器
  • 真正同时执行
  • 性能显著提升

实现方式:

  • 多核处理
  • 分布式计算
  • GPU并行计算

4、并发 vs 并行

并发:

时间片交替执行
单核CPU
看似同时运行

A    B    C
--|--|--|

并行:

真正同时执行
多核CPU
实际同时运行

A B C
-----

5、并发编程模型

同步模型:

  • 阻塞
  • 非阻塞
  • 同步
  • 异步

通信模型:

    共享内存

    消息传递

    Actor模型

    CSP模型

6、并发编程挑战

常见问题:

  • 竞争条件
  • 死锁
  • 资源争用
  • 线程安全

解决策略:

    互斥锁

    信号量

    原子操作

    无锁编程

7、代码示例

并发示例:

// 并发执行
void concurrentTask() {
    std::thread t1([]{ 
        // 任务A 
    });
    
    std::thread t2([]{ 
        // 任务B 
    });

    t1.join();
    t2.join();
}

并行示例:

// 并行计算
void parallelCompute(std::vector<int>& data) {
    // 使用并行算法
    std::for_each(
        std::execution::par,  // 并行执行
        data.begin(), 
        data.end(), 
        [](int& value) {
            value *= 2;  // 并行处理每个元素
        }
    );
}

 8、并发级别

    进程级并发

    线程级并发

    指令级并行

    数据级并行

9、应用场景

适合并发/并行:

    科学计算

    图形渲染

    大数据处理

    网络服务器

    实时系统

10、性能考虑

性能影响因素:

  • 任务granularity
  • 通信开销
  • 同步机制
  • 硬件配置

优化策略:

  • 最小化锁竞争
  • 减少上下文切换
  • 负载均衡
  • 选择合适并发粒度
  • 现代C++并发支持

标准库支持:

  • <thread>
  • <mutex>
  • <condition_variable>
  • <future>
  • <atomic>

选择依据:

  • 任务特性
  • 硬件配置
  • 性能需求
  • 复杂度

建议:

  • 优先考虑并发
  • 评估并行收益
  • 使用高级抽象
  • 谨慎设计

 二、代码实践

1、函数指针创建线程

#include <iostream>
#include <thread>

// 普通函数
void threadFunction(int param) {
    std::cout << "Thread with param: " << param << std::endl;
}

int main() {
    // 使用函数指针创建线程
    std::thread t1(threadFunction, 42);
    t1.join();
    return 0;
}

2、多种函数指针类型

// 不同签名的函数指针
void simpleFunction() {
    std::cout << "Simple function" << std::endl;
}

void paramFunction(int x, double y) {
    std::cout << "Params: " << x << ", " << y << std::endl;
}

int main() {
    // 无参函数
    std::thread t1(simpleFunction);
    
    // 多参数函数
    std::thread t2(paramFunction, 10, 3.14);
    
    t1.join();
    t2.join();
}

3、函数指针与引用传递

void referenceFunction(int& value) {
    value *= 2;
}

int main() {
    int x = 5;
    
    // 使用std::ref传递引用
    std::thread t(referenceFunction, std::ref(x));
    t.join();
    
    std::cout << "Modified x: " << x << std::endl; // 输出10
}

4、类成员函数线程

class Worker {
public:
    void memberFunction(int param) {
        std::cout << "Member function: " << param << std::endl;
    }
    
    static void staticMemberFunction(int param) {
        std::cout << "Static member function: " << param << std::endl;
    }
};

int main() {
    Worker worker;
    
    // 成员函数线程
    std::thread t1(&Worker::memberFunction, &worker, 100);
    
    // 静态成员函数线程
    std::thread t2(Worker::staticMemberFunction, 200);
    
    t1.join();
    t2.join();
}

5、函数指针与Lambda结合

int main() {
    // 使用函数指针类型的Lambda
    auto lambdaFunc = [](int x) {
        std::cout << "Lambda thread: " << x << std::endl;
    };
    
    std::thread t(lambdaFunc, 42);
    t.join();
    
    // 动态函数指针
    typedef void (*FuncPtr)(int);
    FuncPtr ptr = lambdaFunc;
    
    std::thread t2(ptr, 100);
    t2.join();
}

 6、高级函数指针线程池

#include <vector>
#include <functional>
#include <mutex>

class ThreadPool {
private:
    std::vector<std::thread> threads;
    std::mutex mutex;

public:
    // 使用函数指针创建线程
    void addThread(void (*func)(int), int param) {
        std::lock_guard<std::mutex> lock(mutex);
        threads.emplace_back(func, param);
    }

    // 使用std::function更灵活
    void addThreadFunc(std::function<void()> func) {
        std::lock_guard<std::mutex> lock(mutex);
        threads.emplace_back(func);
    }

    void joinAll() {
        for (auto& t : threads) {
            if (t.joinable()) {
                t.join();
            }
        }
    }
};

// 示例函数
void workerFunc(int id) {
    std::cout << "Worker " << id << " running" << std::endl;
}

int main() {
    ThreadPool pool;
    
    // 使用函数指针创建线程
    pool.addThread(workerFunc, 1);
    pool.addThread(workerFunc, 2);
    
    // 使用Lambda
    pool.addThreadFunc([]() {
        std::cout << "Lambda thread" << std::endl;
    });
    
    pool.joinAll();
}

 7、安全的函数指针线程管理

class SafeThread {
private:
    std::unique_ptr<std::thread> thread;
    std::atomic<bool> stop{false};

public:
    template<typename Func, typename... Args>
    void start(Func&& func, Args&&... args) {
        // 确保之前的线程已结束
        if (thread && thread->joinable()) {
            thread->join();
        }
        
        // 创建新线程
        thread = std::make_unique<std::thread>(
            std::forward<Func>(func), 
            std::forward<Args>(args)...
        );
    }

    void stop() {
        stop = true;
        if (thread && thread->joinable()) {
            thread->join();
        }
    }

    ~SafeThread() {
        stop();
    }
};

 8、注意事项

  • 避免悬空指针
  • 使用std::ref传递引用
  • 注意生命周期管理
  • 使用智能指针管理资源
  • 考虑线程安全

9、性能建议

  • 尽量减少线程创建开销
  • 使用线程池
  • 避免频繁创建和销毁线程
  • 选择合适的线程数

10、错误处理

try {
    std::thread t(threadFunction);
    t.join();
} catch (const std::system_error& e) {
    std::cerr << "Thread error: " << e.what() << std::endl;
}


http://www.kler.cn/a/455407.html

相关文章:

  • win11永久修改pdf默认打开方式
  • xwd-ant组件库笔记
  • C/C++ 数据结构与算法【树和森林】 树和森林 详细解析【日常学习,考研必备】带图+详细代码
  • kafka的备份策略:从备份到恢复
  • 【漫话机器学习系列】022.微积分中的链式求导法则(chain rule of Calculus)
  • 爬虫代理服务要怎么挑选?
  • SuperMap iDesktopX填补三维可视化地图海岸地形
  • MySQL 性能瓶颈,为什么 MySQL 表的数据量不能太大?
  • Vue axios 异步请求,请求响应拦截器
  • Hive SQL和Spark SQL的区别?
  • PHP实现登录和注册(附源码)
  • Java并发编程框架之综合案例—— 大数据分析工具(六)
  • Linux | Ubuntu零基础安装学习cURL文件传输工具
  • 【gopher的java学习笔记】@ComponentScan注解解析
  • leetcode hot 100 二叉搜索
  • Qt 信号和槽 connect()第5个参数
  • 利用Python爬虫在速卖通按关键字搜索商品案例指南
  • Windows配置cuda,并安装配置Pytorch-GPU版本
  • STM32-笔记12-实现SysTick模拟多线程流水灯
  • QML和QWidget混合编程方式
  • MySQL —— 配置文件
  • vue3 ref reactive响应式数据,赋值的问题、解构失去响应式问题
  • 下划线表示任意单个字符引发的bug
  • 三相电的相电压、线电压、额定值、有效值,变比,零序电压,零序电流,三相三线制的三角形连接,三相四线制的星形连接
  • C++ 学生成绩信息管理
  • Unity开发AR之Vuforia-MultiTarget笔记