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

文章目录

一、std::ref`的作用

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

cpp 复制代码
void Print1(size_t n, const std::string& s, std::mutex& m, int& rx);

  如果直接这样传递参数会报错:

  同时在线程函数中对a修改,不会影响外部实参,因为:线程函数参数虽然是引用方式,但其实际引用的是线程栈中的拷贝

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

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

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

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

cpp 复制代码
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的构造函数利用了模板可变参数,能够接受任意类型的参数,并将它们转发给线程函数。例如:

cpp 复制代码
template <class F, class... Args>
explicit std::thread(F&& f, Args&&... args);

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

(二)引用折叠

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

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

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

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

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

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

相关推荐
sunshine22 girl32 分钟前
Java学习六 Java常见API-1-Radom随机数
java·开发语言·学习
可乐鸡翅yeah_35 分钟前
hls.js 手动自定义 http 请求 loader,修改请求头实战
开发语言·前端·javascript·网络协议·http·ecmascript·m3u8在线
潼心1412o1 小时前
C++初阶(长期更新)第6讲:类和对象(下)
开发语言·c++·算法
夜晚回家1 小时前
Python 零基础入门 | 输入的数字为什么不能直接算
开发语言·python
时间的拾荒人1 小时前
Qt 事件机制全解析:从事件处理到事件过滤器
开发语言·qt·面试
-森屿安年-1 小时前
按身高排序
c++·算法
于指尖飞舞1 小时前
java面试题总结
java·开发语言
(Charon)3 小时前
【C++面试】vector底层原理:扩容、拷贝移动与迭代器失效
c++·面试
zhangzeyuaaa3 小时前
深入理解 Ruby 运算符:本质、分类、坑点与重载实战
开发语言·前端·ruby
一木 之林3 小时前
DeepSeek Agent 开发(一)
开发语言·前端·javascript