Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is changing a pointer considered an atomic action in C?

If I have a multi-threaded program that reads a cache-type memory by reference. Can I change this pointer by the main thread without risking any of the other threads reading unexpected values.

As I see it, if the change is atomic the other threads will either read the older value or the newer value; never random memory (or null pointers), right?

I am aware that I should probably use synchronisation methods anyway, but I'm still curious.

Are pointer changes atomic?

Update: My platform is 64-bit Linux (2.6.29), although I'd like a cross-platform answer as well :)

like image 225
Andrioid Avatar asked May 18 '09 18:05

Andrioid


People also ask

Are pointers Atomic?

The main risk is that only ptr is atomic. But this does not apply to the values pointed to. To be noted that especially pointers bring further synchronisation risk when you reassign the atomic pointer to a non atomic pointer.

Is pointer assignment atomic in C?

Depending on the compiler and the platform, the pointer assignment may or may not be atomic. C++11 does define a threading behavior and the associated memory model.

Can pointers be any type?

A void pointer can hold addresses of any type and can be typecast to any type. It is also called a generic pointer and does not have any standard data type.

Can a pointer be any type in C?

void pointer in C / C++A void pointer can hold address of any type and can be typecasted to any type.


1 Answers

As others have mentioned, there is nothing in the C language that guarantees this, and it is dependent on your platform.

On most contemporary desktop platforms, the read/write to a word-sized, aligned location will be atomic. But that really doesn't solve your problem, due to processor and compiler re-ordering of reads and writes.

For example, the following code is broken:

Thread A:

DoWork(); workDone = 1; 

Thread B:

while(workDone != 0);  ReceiveResultsOfWork(); 

Although the write to workDone is atomic, on many systems there is no guarantee by the processor that the write to workDone will be visible to other processors before writes done via DoWork() are visible. The compiler may also be free to re-order the write to workDone to before the call to DoWork(). In both cases, ReceiveResultsOfWork() might start working on incomplete data.

Depending on your platform, you may need to insert memory fences and so on to ensure proper ordering. This can be very tricky to get right.

Or just use locks. Much simpler, much easier to verify as correct, and in most cases more than performant enough.

like image 171
Michael Avatar answered Oct 05 '22 23:10

Michael