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

inux 基础入门操作 第十章 C++多线程介绍 2

1 C++ 线程介绍

std::thread 是 C++11 标准引入的线程库,提供面向对象的多线程编程接口,比传统的 POSIX 线程(pthread)更易用且类型安全。

1.1 基本用法

  1. 头文件与基本创建
#include <thread>
#include <iostream>

void hello() {
    std::cout << "Hello from thread!\n";
}

int main() {
    // 创建并启动线程
    std::thread t(hello);    
    // 等待线程结束
    t.join();    
    return 0;
}
  1. 带参数的线程函数
void print_num(int num, const std::string& str) {
    std::cout << "Number: " << num << " String: " << str << "\n";
}

int main() {
    std::thread t(print_num, 42, "Answer");
    t.join();
}

1.2 常见的api函数

在这里插入图片描述

1.3 detach() 介绍

  1. 所有权转移:

调用detach()后,std::thread对象不再拥有该线程。线程变为"守护线程"(daemon thread),在后台运行

  1. 资源管理:

分离的线程结束时,系统会自动回收其资源。不需要也不能再调用join()。

  1. 调用限制:

只能在joinable()为true时调用(即新创建且未join/detach过的线程)。调用后joinable()变为false

detach()是一个强大但需要谨慎使用的工具,正确使用可以实现有效的后台任务处理,但不当使用会导致难以调试的问题。在大多数情况下,优先考虑使用join()或更高级的抽象(如std::async或线程池)。

1.3.1 案例

void log_writer() {
    while(true) {
        write_logs();
        std::this_thread::sleep_for(std::chrono::minutes(1));
    }
}

int main() {
    std::thread t(log_writer);
    t.detach();
    // ... 主程序继续
}

2 同步设置

2.1 互斥锁

互斥锁是多线程编程中最基础的同步机制,用于保护共享数据,防止多个线程同时访问造成的数据竞争问题。C++11在标准库中引入了多种互斥锁类型。

2.1.1 一般应用

#include <mutex>
#include <thread>

std::mutex mtx;  // 全局互斥锁
int shared_data = 0;

void increment() {
    mtx.lock();    // 加锁
    ++shared_data; // 临界区
    mtx.unlock();  // 解锁
}


2.1.2 更加安全应用

  1. std::lock_guard 最简单的RAII锁管理,构造时加锁,析构时解锁
{
    std::lock_guard<std::mutex> lock(mtx);  // 进入作用域加锁
    // 临界区代码
} // 离开作用域自动解锁
  1. std::unique_lock 更灵活的RAII锁管理,支持延迟锁定、条件变量等。
std::unique_lock<std::mutex> lock(mtx, std::defer_lock); // 延迟加锁
if(lock.try_lock()) {  // 手动尝试加锁
    // 临界区代码
}

案例如下

#include <mutex>

std::mutex mtx;
int shared_data = 0;

void safe_increment() {
    std::lock_guard<std::mutex> lock(mtx);
    ++shared_data;
}

2.2 条件变量

条件变量是多线程编程中用于线程间同步的重要机制,它允许线程在某个条件不满足时挂起,直到其他线程通知条件可能已发生变化。

条件变量总是与互斥锁配合使用,主要解决以下问题:

  1. 线程需要等待某个条件成立

  2. 避免忙等待(busy-waiting)造成的CPU资源浪费

  3. 实现高效的线程间通信

2.2.1 基本组件

#include <condition_variable>

std::mutex mtx;                  // 互斥锁
std::condition_variable cv;       // 条件变量
bool ready = false;               // 共享条件

2.2.2 等待

std::unique_lock<std::mutex> lock(mtx);
cv.wait(lock, []{ return ready; });  // 条件不满足时自动释放锁并等待
// 条件满足后继续执行,锁已重新获取

运行案例:

#include <condition_variable>

std::mutex mtx;
std::condition_variable cv;
bool ready = false;

void worker() {
    std::unique_lock<std::mutex> lock(mtx);
    cv.wait(lock, []{ return ready; });
    // 处理数据
}

void controller() {
 {
        std::lock_guard<std::mutex> lock(mtx);
        ready = true;
    }
    cv.notify_all();
}

3 与pthread的区别

在这里插入图片描述

4 问题

4.1 资源泄漏风险

void risky_function() {
    std::thread t(heavy_task);
    if(some_condition) {
        throw std::runtime_error("Oops");
        // 线程t未被join,导致资源泄漏
    }
    t.join();
}

4.2 过渡创建

for(int i=0; i<1000; ++i) {
    std::thread t(short_task);  // 频繁创建/销毁线程代价高
    t.detach();
}

5 线程池

线程池是一种多线程处理形式,它预先创建一组线程并维护这些线程的生命周期,通过任务队列机制来处理并发任务。线程池是现代并发编程的基础设施,合理使用可以显著提升程序性能,同时降低系统资源消耗。开发者应根据具体场景选择合适的线程池实现和配置参数。

// 使用线程池示例(伪代码)
ThreadPool pool(4);  // 4个工作线程

for(auto& task : tasks) {
    pool.enqueue(task);  // 任务排队执行
}

相关文章:

  • 计算齿轮故障频率|平行轴|行星轮齿轮
  • 八股系列(分布式与微服务)持续更新!
  • 初阶数据结构--链式二叉树
  • 解决电脑问题——突然断网!
  • 有宽阔的意思的单词
  • 2025认证杯一阶段各题需要使用的模型或算法(冲刺阶段)
  • Python及C++中的集合
  • 【软考系统架构设计师】信息安全技术基础
  • JVM 常用字节码指令有哪些?
  • swift ui基础
  • 生物信息Rust-01
  • 详解PyTorch框架Tensor基础操作
  • 【深度学习基础】神经网络入门:从感知机到反向传播
  • [python] reduce
  • 38.[前端开发-JavaScript高级]Day03-深入JS执行原理-作用域链-JS内存管理-闭包
  • 内网dns权威域名服务器搭建
  • 【力扣hot100题】(092)最长回文串
  • 颜色在线工具
  • 十九、UDP编程和IO多路复用
  • 基于vue框架的住院信息管理系统k08hv(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
  • 建设通网站vip/网店培训骗局
  • 长春网站建设流程/百度云网盘资源搜索
  • html5技术可以制作网站吗/推广app赚佣金接单平台
  • 做网站有一个火箭回顶部/域名whois查询
  • 有趣的网站有哪些推荐/给公司建网站需要多少钱
  • 网站空间换了 使用原有域名/关于普通话的手抄报