C ++ 11 - am I safe to pass a local variable as an argument to a stream

I have this code

#include <thread> typedef struct { int a; short b; }TestStruct; void TestParamRef(const TestStruct& test) { Sleep(3000); /*Sleep to wait for the caller function end*/ TestStruct i = test; /*Test if the argument still ok*/ } void TestParamPointer(TestStruct* test) { Sleep(4000); /*Sleep to wait for the caller function end*/ TestStruct i = *test; /*Test if the argument still ok*/ } void Test() { TestStruct localTest; /*Local variable should be destroyed after this Test function end*/ localTest.a = localTest.b = 69; std::thread threadRef(TestParamRef, localTest); threadRef.detach(); /*Bye bye thread*/ localTest.a = 6969; std::thread threadPointer(TestParamPointer, &localTest); threadPointer.detach();/*Bye bye thread*/ localTest.b = 696969; } int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { Test(); /*Put break point here*/ return 0; } 

As you can see in the code, I'm trying to check what happens if I pass a local variable to a stream, and this local variable is destroyed before the stream is used. And I find out that TestParamPointer gets a ridiculous value (perhaps because it now points to the basket value), but TestParamRef still gets the correct value.

So, I wonder if the thread really stores its argument in its own memory? I thought that when I use 'const TestStruct & test', the function will not copy the entire parameter, but reuse this parameter (I use this when the parameter is quite large - like sql table data). So how does it work? This is safe when I pass a local variable to the stream.

+5
source share
1 answer

std :: thread will copy or move any argument you pass to it, so yes, it is thread safe.

Passing a raw pointer, on the other hand, is not thread safe. In fact, passing a pointer to a local variable in a separate thread is doubly bad, because the thread is not guaranteed to complete before your local variable goes out of scope (you do not use .join () to block until the thread is completed) , Later, when a thread bypasses its work, it may or may not work on something that could lead to a failure.

http://en.cppreference.com/w/cpp/thread/thread/thread

The arguments to the stream function are moved or copied by value. If the reference argument is to be passed to the stream function, it has to be wrapped (for example, using std :: ref or std :: cref).

Also, if you terminate the link using std :: ref, it becomes unsafe because it can be obtained from the original context, so you will need to provide a synchronization method (mutex / lock, thread-safe container, or whatever you have).

+7
source

Source: https://habr.com/ru/post/1271381/


All Articles