C ++ understanding multithreading with global variables

I have a C ++ program that declares some global variables. After that, it is split into several threads to complete several tasks. These threads read and write some of these global variables.

Will there be an application error if two threads are reading the same variable? Or can an application crash only if one thread writes to a variable that another thread reads?

So, if the answer to my second question is yes, will the following code example solve this problem?

#include <string> #include <thread> #include <mutex> using namespace std; mutex m; string var = "foo"; // function to provide read and write access // "protected" with mutex string test(string value = "") { m.lock(); if (value == "") { m.unlock(); return var; } else { var = value; m.unlock(); return ""; } } void thread1() { // use global variable local string localVar = test(); } void thread2() { // overwrite global variable test("bar"); } void thread3() { // use global variable local string localVar = test(); } int main() { thread t1(thread1); thread t2(thread2); thread t3(thread3); t1.join(); t2.join(); t3.join(); return 0; } 

in addition: this part

 // ... if (value == "") { m.unlock(); return var; } // ... 

also save stream?

And my last question: my program currently uses only one mutex to prevent two threads from starting simultaneously (the same function!). I do not use mutexes for my global variables. Maybe this "situation" can lead to a crash of the application (module: "ntdll.dll") with exception code 0xc0000005?

Thanks in advance!

+6
source share
5 answers

Mutual reads are always reliable in the stream. As soon as one thread writes a non-atomic var variable while other threads read with var , you are at risk of a race condition. So, you are almost there, but you are using mutex security devices (they are RAII and therefore exclude safe and clean C ++), something like:

 #include <mutex> #include <string> // ... std::mutex m; std::string var = "foo"; // ... std::string test(const std::string& value = "") { std::lock_guard<std::mutex> lock(m); if (value == "") { return var; } else { var = value; return ""; } } 
+6
source

Will there be an application error if two threads are reading the same variable?

No. Never. If you read from only a few threads, you are always safe.

Will an application crash only if one thread writes to a variable that another thread reads?

Not really, but it can crash, as well as what happens in your code. This is not “dangerous” from the point of view of the failure of the read / write application from several threads simultaneously. The worst case is that you get stolen valuables in some places. What belongs to them will not cause your application to crash, but ultimately it can lead to this. The problem is that the data you are reading has a value other than a primitive value (e.g. an integer). For example, if you read the memory address (pointer), and then try to access the memory at that address, but the memory is already freed, then you have problems - and what happens in your code. Line characters have moved to the new address, but you are trying to read the old address.

To solve your problem, you have to wrap the whole operation inside the lock, and for this you can use a temporary variable:

 string test(string value = "") { m.lock(); if (value == "") { string temp = var; m.unlock(); return temp; } else { var = value; m.unlock(); return ""; } } 

Strike>

The correct decision is in Paul's answer.

+5
source

Simple question, simple answer:

Will there be an application error if two threads read the same variable?

No.

Will there be an application error only if one thread writes to a variable that another thread reads?

No.

However, you really should use locks and mutexes, etc. to make sure you get the expected result for programs. Although the program itself will not crash if one stream writes to a variable read by another stream, what value do you want the read stream to actually read? Value before it was written to / over or value after?

0
source

Insecure thread without mutexes

The proposed solution is still not entirely correct.

var is read outside the mutex and can be changed at this time.

This is similar to C ++ 11. If std::string used common strings (forbidden in C ++ 11), this could cause reading problems.

In the case of reading + writing, then c0000005 (violation of access rights) can occur if the pointer was changed as it was copied.

0
source

Will there be an application error if two threads read the same variable?

No, you can safely read the global variable at the same time (if you know that no one writes it at the same time). The read operation does not change the global value, therefore it remains unchanged, and all readers "see" the same value.

Or will an application crash only if one thread writes to a variable that another thread reads?

As a rule, no, at least not because of the simultaneous read and write operations. Crashing can be a side effect. For example, if you update a pointer value and read it at the same time, you are trying to access the data that the pointer points to. If the reading value is not valid, most likely you will crash.

in addition: this part

 // ... if (value == "") { m.unlock(); return var; } // ... 

also save stream?

No. Your mutex m only protects the local variable value , which does not need to be protected, since it is local. But then you release the mutex and copy ( read ) the global variable var , while another thread can write it. To make it thread safe, use std::lock_guard and you won’t need to manually lock / unlock mutexes. or update the code:

 m.lock(); if (value == "") { string ret_val(var); m.unlock(); return ret_val; } 

I do not use mutexes for my global variables. Maybe this “situation” may cause the application to crash

As I wrote earlier, yes, as a side effect, the application may crash.

0
source

All Articles