3

This would be done without mutexes. I just want to know if it is thread safe ie the program will not crash or something similar. I do not really care that the variable could be in the wrong state when it is read as the consequence is not fatal (only impact would be making a copy of a small data structure when not necessary) I am using Qt.

Here is the context that could happen: from the main thread, I would be setting a bool that is a member of a qthread. While or after I am setting the bool to true, the qthread could be in the function that uses this bool (this is a function that is used by the main thread and the qthread, everything is already protected and synchronised so as to not have the function being run by both threads simultaneously)

Kinda think of it, since this bool is only used by the main thread anyways I will check which thread is in the function and that should solve that but I am still curious.

yan bellavance
  • 4,710
  • 20
  • 62
  • 93

3 Answers3

12

You seem to be asking about what are called benign races.

For example consider an integer variable representing a progress value in the range 0 to 100. You read it from one thread at the same time as you are incrementing from another. You don't mind whether you read the value before the write or the value after the write. You'll read it again soon and then you'll get the value from after the write. In that scenario the race is benign. However what may not be benign is something called tearing. The hardware may allow you to read the value whilst only some part of the memory has been written to by the other thread.

For example the writing thread may write the low word, then the read of both words occurs and then the high word is written. Tearing can lead to incorrectness.

The hardware does provide guarantees about tearing but they vary between architectures. For example x86 has atomic access, i.e. no tearing, for 4 byte wide data that is 4 byte aligned.

If you are writing portable code then you are in quite tricky waters because the current standard gives no guarantees about atomicity. If you can make assumptions on your hardware platform then you may be able to take advantage of benign races.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • ok thanks that answers alot. I now understand how tearing could be fatal to a program if the variable in question was a pointer. In my case, its a bool which should not cause fatal aborts. In any case I will still avoid doing this. – yan bellavance Jun 21 '11 at 23:58
2

You can do reading without a mutex but not writing. If multiple threads will write to your variable, you need to have some sort of synchronization mechanism to protect it.

If thread B reads before thread A has finished it's write, you could get inconsistent state if this is not a simple type, but some complex type.

Tony The Lion
  • 61,704
  • 67
  • 242
  • 415
  • 5
    You could get inconsistencies even for simple types. – Oliver Charlesworth Jun 21 '11 at 23:40
  • @Oli, I guess that's because no writes are guaranteed to be atomic? – Tony The Lion Jun 21 '11 at 23:42
  • I am not concerned about getting a true when I should be getting a false but rather I do not want access violations or segmentation faults or crashes – yan bellavance Jun 21 '11 at 23:43
  • 2
    @Tony: That's correct. I suppose the only exception would reasonably be `char`, but it's best not to risk it. Always synchronise! – Oliver Charlesworth Jun 21 '11 at 23:44
  • @Tony, i guess I could look into the QAtomicInt class – yan bellavance Jun 21 '11 at 23:44
  • @you guys, yeah I was looking into this because I did not want to add another input parameter to my function which calls a few other functions before it uses the parameter. I could just send a structure as input to the func but... – yan bellavance Jun 21 '11 at 23:46
  • the big question though is , can it crash the prog. It's a bool. – yan bellavance Jun 21 '11 at 23:46
  • writes to a bool are not **guarantueed** to be atomic. If you're going to write to it, you need to SYNCH!!! Don't take the risk! – Tony The Lion Jun 21 '11 at 23:48
  • @Tony: Yes, that's the reason. See [this](http://stackoverflow.com/questions/54188/are-c-reads-and-writes-of-an-int-atomic) discussion for more details. – thorsten müller Jun 21 '11 at 23:49
  • 1
    @yan Even if writing to a `bool` is not guaranteed to be atomic, it is reasonable to assume. And if not, what would you get, some strange value not from {0,1}, that should just be treated as `true` by the program. So you're fine, don't let the synchronization paranoia get you! – Christian Rau Jun 22 '11 at 00:00
  • Hi @Tony The Lion what would happen if LITERALLY a variable is updated by one thread and another thread reads it EXACTLY AT THE SAME TIME (Considering there is no synchronization)? Thanks in advance –  Nov 01 '22 at 18:45
  • That's correct. I suppose the only exception would reasonably be char, but it's best not to risk it. Always synchronise! - Hi @Oliver Charlesworth then, we can say that "ALWAYS when a variable is going to be updated by several threads we MUST synchronize the access YES OR YES" regardless of the data type –  Nov 01 '22 at 18:48
1

You don't mention a platform, but if you're an Windows you should definitely look at the ::Interlocked... family of SDK functions when dealing with simpler types.

Johann Gerell
  • 24,991
  • 10
  • 72
  • 122