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

『 C++ 』多线程编程中的参数传递技巧

文章目录

  • 一、std::ref`的作用
  • 二、 使用指针和lambda表达式的好处<br><br>
  • 三、模板可变参数与引用折叠
    • (一)模板可变参数
    • (二)引用折叠

一、std::ref`的作用

  在多线程编程中,std::ref是一个非常有用的工具,它允许我们将引用传递给线程函数,而不是传递副本。这在某些情况下可以避免不必要的拷贝,提高效率。例如:

void Print1(size_t n, const std::string& s, std::mutex& m, int& rx);

  如果直接这样传递参数会报错:
  同时在线程函数中对a修改,不会影响外部实参,因为:线程函数参数虽然是引用方式,但其实际引用的是线程栈中的拷贝

// unknown-type std::invoke(_Callable &&,_Ty1 &&,_Types2 &&...) noexcept(<expr>)
std::thread t1(Print1, 100, "hello mutex", std::ref(mtx), std::ref(x));

  这里std::refmtxx的引用传递给了线程函数Print1,而不是它们的副本。如果不使用std::refmtxx将会被拷贝,这可能导致线程间无法正确共享资源。

二、 使用指针和lambda表达式的好处

  在多线程编程中,线程函数的参数传递是一个关键问题。使用指针和lambda表达式可以有效避免引用带来的麻烦。例如,lambda表达式可以捕获上下文变量,并以值或引用的方式传递给线程函数,简化代码并避免引用悬挂或生命周期问题。

void Print(size_t n, size_t j, const std::string& s) {
    for (size_t i = j; i < j + n; i++) {
        std::cout << std::this_thread::get_id() << " " << s << ": " << i << std::endl;
    }
}

int main() {
    std::thread t1(Print, 100, 1, "Thread 1");
    std::thread t2([=]() {
        Print(100, 101, "Thread 2");
    });
    t1.join();
    t2.join();
    return 0;
}

三、模板可变参数与引用折叠

(一)模板可变参数

模板可变参数是C++11引入的一个强大特性,它允许函数接受任意数量和类型的参数。std::thread的构造函数利用了模板可变参数,能够接受任意类型的参数,并将它们转发给线程函数。例如:

template <class F, class... Args>
explicit std::thread(F&& f, Args&&... args);

这里的Args&&... args表示可变参数模板,std::thread会将这些参数转发给线程函数。

(二)引用折叠

引用折叠是C++11中引入的一个机制,用于处理引用的传递和绑定。它的主要规则如下:

• 左值引用折叠:如果一个引用被绑定到一个左值,那么它会被折叠为左值引用。

• 右值引用折叠:如果一个引用被绑定到一个右值,那么它会被折叠为右值引用。

• 混合引用折叠:如果一个引用被绑定到一个左值或右值,那么它会被折叠为左值引用。

引用折叠的作用是确保参数的正确传递,避免不必要的拷贝和悬挂引用问题。例如:

注意:如果是类成员函数作为线程参数时,必须将this作为线程函数参数。

相关文章:

  • 23 种设计模式中的访问者模式
  • 【大模型算法工程】大模型应用工具化、忠诚度以及知识库场景下PDF双栏解析问题的讨论
  • 视点游动生成光照贴图
  • 3.21学习总结 Java字符串+Static关键字
  • AI Agent开发大全第一课-AI是什么以及如何使用AI
  • Unity代码中修改动画速度
  • Python 面向对象三大特性深度解析
  • C#与西门子PLC的六大通信库
  • VSCode中搜索插件显示“提取扩展时出错。Failed to fetch”问题解决!
  • java基础--序列化与反序列化的概念是什么?
  • 大数据学习(80)-数仓分层
  • Spring 三级缓存能不能解决循环依赖?
  • 概率预测之NGBoost(Natural Gradient Boosting)回归和分位数(Quantile Regression)回归
  • KNN算法
  • Spring Boot中接口数据字段为 Long 类型时,前端number精度丢失问题解决方案
  • Vue入门
  • 油候插件、idea、VsCode插件推荐(自用)
  • 申请使用受限权限
  • 深入解析:Nginx+Keepalived实现双机热备架构
  • 《汽车电器与电子技术》第四次作业
  • 兵韬志略|美2026国防预算未达1万亿,但仍寻求“暗度陈仓”
  • 巴基斯坦军方:印度导弹袭击巴首都附近空军基地
  • 本周看啥|喜欢二次元的观众,去电影院吧
  • 中日有关部门就日本水产品输华问题进行第三次谈判,外交部回应
  • 乡村快递取件“跑腿费”屡禁不止?云南元江县公布举报电话
  • 如此城市|上海老邬:《爱情神话》就是我生活的一部分