Short answer: No, there is no general guarantee that a will be updated. My suggestion was to send the value of a along with "foo" - for example. "foo, 42" , or something like that. This is guaranteed to work, and probably will not have significant overhead. [Of course, there may be other reasons why this works poorly]
Long rambling things that don't really answer the problem:
Global data is not guaranteed to be "visible" immediately in different cores of multicore processors without further operations. Yes, most modern processors are “consistent”, but not all models of all brands guarantee this. Therefore, if thread2 runs on a processor that has already cached a copy of a , it cannot be guaranteed that the value of a is 42 at the point when you call f .
The C ++ standard ensures that global variables are loaded after a function call, so the compiler is not allowed to do:
tmp = a; recv(...); f(tmp);
but, as I said above, cache operations may be required to ensure that all processors see the same value at the same time. If send and recv are long or large in access enough [there is no direct measure that says how long or large) you can see the correct value more or even all the time, but there is no guarantee for ordinary types that they are ACTUALLY updated out of stream, who wrote the value last.
std::atomic will help on some types of processors, but there is no guarantee that it is "visible" in the second thread or on the second processor core at any reasonable time after changing it.
The only practical solution is to have some kind of "repeat while I see it" code, this may require one value, which (for example) is a counter, and one value is the actual value - if you want to say that "now 42. I installed again, this time also 42." If a reproduced, for example, the number of data items available in the buffer, it probably means “he changed the value”, and just checking “this is the same as last time”. The std::atomic operations have guarantees with respect to order, which allows them to be used to ensure that "if I update this field, another field will be guaranteed to appear at the same time or before." Thus, you can use this to ensure, for example, that a pair of data items has a value of "there is a new value" (for example, a counter indicates a "version number" of current data) and a "new value is X",
Of course, if you KNOW what processor architecture your code will run on, you can make more complex guesses about what the behavior will be. For example, all x86 and many ARM processors use the cache interface to implement atomic updates for a variable, so when doing atomic updates on one core, you may know that "no other processor will have an outdated value." But there are processors available that do not have this implementation detail, and where the update, even using the atomic instruction, will not be updated on other kernels or in other threads until “for some time in the future is uncertain”.