c++11仔细地将参数传递给线程std::thread

要将参数传递给线程的可关联对象或函数,只需将参数传递给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;
}

怎样给线程传递函数
不要将本地堆栈变量的地址传递给线程的回调函数,因为线程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;
}  

同样的,在将指针传递给位于heap上的线程时,要小心,因为某些线程可能在新线程尝试访问它之前删除该内存。
在这种情况下,访问无效地址可能会导致不可预测的行为。

例如:

#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* p = new int();
  *p = 10;
  std::cout << "Inside Main Thread :  "" : *p = " << *p << std::endl;
  std::thread t(newThreadCallback, p);
  t.detach();
  delete p;
  p = NULL;
}
 
int main() {
  startNewThread();
  std::chrono::milliseconds dura(2000);
  std::this_thread::sleep_for(dura);
  return 0;
}  

给线程传递引用

由于参数被复制到新的线程堆栈,所以,如果想通过常用的方式传递引用,如:

#include <iostream>
#include <thread>
 
void threadCallback(int const& x) {
  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接受参数作为引用,但是并没有改变main中x的值,在线程引用外它是不可见的。
这是因为线程函数threadCallback中的x是引用复制在新线程的堆栈中的临时值。

如何修改:
使用 std::ref
 

#include <iostream>
#include <thread>
 
void threadCallback(int const& x) {
  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 

指定一个类的成员函数的指针作为线程函数。将指针传递给成员函数作为回调函数,并将指针指向对象作为第二个参数

本文转自:c++11多线程编程(三):仔细地将参数传递给线程_小麒麟的成长之路-CSDN博客

#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;
}  

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值