I wrote some multithreaded but lock-free code that compiled and apparently executed fine on an earlier C++11-supporting GCC (7 or older). The atomic fields were int
s and so on. To the best of my recollection, I used normal C/C++ operations to operate on them (a=1;
, etc.) in places where atomicity or event ordering wasn't a concern.
Later I had to do some double-width CAS operations, and made a little struct with a pointer and counter as is common. I tried doing the same normal C/C++ operations, and errors came that the variable had no such members. (Which is what you'd expect from most normal templates, but I half-expected atomic
to work differently, in part because normal assignments to and from were supported, to the best of my recollection, for int
s.).
So two part question:
-
Should we use the atomic methods in all cases, even (say) initialization done by one thread with no race conditions? 1a) so once declared atomic there's no way to access unatomically? 1b) we also have to use the verboser verbosity of the
atomic<>
methods to do so? -
Otherwise, if for integer types at least, we can use normal C/C++ operations. But in this case will those operations be the same as
load()
/store()
or are they merely normal assignments?
And a semi-meta question: is there any insight as to why normal C/C++ operations aren't supported on atomic<>
variables? I'm not sure if the C++11 language as spec'd has the power to write code that does that, but the spec can certainly require the compiler to do things the language as spec'd isn't powerful enough to do.
Aucun commentaire:
Enregistrer un commentaire