C++:nitty-gritty place in the Standard Thread Library

Scenario 1:

1 void f(int i,const string s);
2 void oops(int some_param)
3 {
4     char buffer[1024];
5     sprintf(buffer,"%i",some_param);
6     std::thread t(f,3,buffer);
7     t.detach();
8 }

The problem is, there's a significant chance that the function  oops will exit before the  buffer  has been converted to a  std::string ,thus leading to undefined behavior. Note that in this case, the constructor of  std::thread just copies the supplied values(which is  buffer  the pointer) as is, without converting it to the expected argument type. That conversion is left to to function  f  itself. So after the constructor of  std::thread copy  buffer and before  buffer  be converted to  std::string , function  oops may have exited and  buffer  would be destroyed then, making the convertion afterward illegal.

Scenario 2 (to pass reference as parameter to a thread function):

 1 void update_data_for_widget(widget_id w, widget_data& data);
 2 
 3 void oops_again(widget_id w)
 4 {
 5     widget_data data;
 6     std::thread t(update_data_for_widget,w,data);
 7     do_something();
 8     t.join();
 9     process_widget_data(data);
10 }

Obviously, in line 6,  data would be pass as a copy rather than a reference to function  update_data_for_widget . To really pass it as a reference, you have to do this:

std::thread t(update_data_for_thread,w,std::ref(data));

Scenario 3( Using member function as a thread function ) :

Note that the behavior of  std::thread  constructor is defined in terms of the same mechanism as the operation of  std::bind . This means that, for example, you can pass a member function pointer as the function, provided you supplied a suitable object pointer as the first argument:

1 class X
2 {
3 public:
4     void do_some_work();
5 };
6 
7 X my_x;
8 std::thread t(&X::do_some_work,&my_x);   //If you don't know how can this be, check std::bind

This code would invoke  my_x.do_some_work() on the new thread, because the address of  my_x is supplied as the object pointer( If you don't know how can this be, check  std::bind  )

You can also supply arguments to such a member function call: the third argument to the  std::thread constructor would be the first argument to the member function and so forth.

:)

原文地址:https://www.cnblogs.com/walkerlala/p/5386882.html