C++11多线程 – Part 3: 为线程传递参数

翻译:https://thispointer.com//c11-multithreading-part-3-carefully-pass-arguments-to-threads/

为了给一个线程相关联的调用对象或函数传递参数,仅仅只需要在std::thread构造时传递额外的参数。
默认情况下,所有参数都被复制到新线程的内部存储中。

让我们看一个例子:

在C++11中将普通参数传递给std::thread

#include <iostream>
#include <string>
#include <thread>
void threadCallback(int x, std::string str)
{
    std::cout << "Passed Number = " << x << std::endl;
    std::cout << "Passed String = " << str << std::endl;
}
int main()
{
    int x = 10;
    std::string str = "Sample String";
    std::thread threadObj(threadCallback, x, str);
    threadObj.join();
    return 0;
}
/*输出结果
Passed Number = 10
Passed String = Sample String
*/

在C++11中如何将参数不传递给线程

不要将本地栈中的变量地址传递给线程的回调函数。因为线程1中的局部变量可能超出范围,但线程2仍试图通过其地址访问它。
在这种情况下,访问无效地址可能会导致意外行为,例如:

#include <iostream>
#include <thread>
void newThreadCallback(int * p)
{
    std::cout<<"Inside Thread :  "" : p = "<<p<<std::endl;
    std::chrono::milliseconds dura( 1000 );
    std::this_thread::sleep_for( dura );
    *p = 19;
}
void startNewThread()
{
    int i = 10;
    std::cout<<"Inside Main Thread :  "" : i = "<<i<<std::endl;
    std::thread t(newThreadCallback,&i);
    t.detach();
    std::cout<<"Inside Main Thread :  "" : i = "<<i<<std::endl;
}
int main()
{
    startNewThread();
    std::chrono::milliseconds dura( 2000 );
    std::this_thread::sleep_for( dura );
    return 0;
}

/*输出结果:
Inside Main Thread :   : i = 10
Inside Thread :   : p = 0x7ffeefbf49cc
Inside Main Thread :   : i = 10
*/

在C++11中如何将引用传递给std::thread

因为参数被复制到新的线程栈中,如果你需要以通用方式传递引用,例如:看看这个

#include <iostream>
#include <thread>
void threadCallback(int const & x)  // 常量传参,线程会将参数拷贝后访问, 这里必须用const,不然会报错
{
    int & y = const_cast<int &>(x);
    y++;
    std::cout<<"Inside Thread x = "<<x<<std::endl;
}
int main()
{
    int x = 9;
    std::cout<<"In Main Thread : Before Thread Start x = "<<x<<std::endl;
    std::thread threadObj(threadCallback, x);
    threadObj.join();
    std::cout<<"In Main Thread : After Thread Joins x = "<<x<<std::endl;
    return 0;
}

/*输出结果
In Main Thread : Before Thread Start x = 9
Inside Thread x = 10
In Main Thread : After Thread Joins x = 9
*/

即使threadCallback接受引用作为参数,但在线程外部仍然看不到所做的更改。
这是因为线程函数threadCallback中的x引用了复制到新线程堆栈中的临时值。
如何修改,使用std::ref()

#include <iostream>
#include <thread>
void threadCallback(int const & x) // 可以不使用const
{
    int & y = const_cast<int &>(x);
    y++;
    std::cout<<"Inside Thread x = "<<x<<std::endl;
}
int main()
{
    int x = 9;
    std::cout<<"In Main Thread : Before Thread Start x = "<<x<<std::endl;
    std::thread threadObj(threadCallback,std::ref(x));
    threadObj.join();
    std::cout<<"In Main Thread : After Thread Joins x = "<<x<<std::endl;
    return 0;
}

/*输出结果
In Main Thread : Before Thread Start x = 9
Inside Thread x = 10
In Main Thread : After Thread Joins x = 10
*/

将指向类的成员函数的指针作为线程函数

将指向成员函数的指针作为回调函数传递,将指向对象的指针作为第二个参数传递。
例如:

#include <iostream>
#include <thread>
class DummyClass {
public:
    DummyClass(){}

    DummyClass(const DummyClass & obj){}
    void sampleMemberFunction(int x)
    {
        std::cout<<"Inside sampleMemberFunction "<< x << std::endl;
    }
};
int main() {
    DummyClass dummyObj;
    int x = 10;
    std::thread threadObj(&DummyClass::sampleMemberFunction,&dummyObj,x);
    threadObj.join();
    return 0;
}

/*输出结果
Inside sampleMemberFunction 10
*/

原文链接: https://www.cnblogs.com/vivian187/p/12706876.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍;

也有高质量的技术群,里面有嵌入式、搜广推等BAT大佬

    C++11多线程 - Part 3: 为线程传递参数

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/342150

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年3月2日 上午1:26
下一篇 2023年3月2日 上午1:27

相关推荐