-1

I wanted to have some practice with async operations, so my goal is to try write a short program that will read and write into the same array. So let's say it is a int array of a thousand indices.

Can I make a async function to go ahead and write let's say all 1's or some random number into all indices from start to end of the array. Then make another async function to read that array from start to end.

That reading function would check if the index it's going to read is =0, and if it does =0, it'll keep checking until it doesn't equal zero. This way there is no need for mutex or atomic operations.

Is that possible? Thank you!

To me this is the simple way to do it, I saw sources online saying I need a mutex or atomic operations but I as I was writing the program I don't see the sense in having a mutex/atomic stuff and I thought of the aforementioned approach and scrapped that old implementation. I am only having one source/function manipulating the array so I don't think it needs a mutex.

TLDR; Is a mutex or atomic operations needed when there is only one writer and one reader to an array?

  • As long as writing and reading happen at different times and you can guarantee this (e.g. only write at initialization of the array). Yes then synchronization is not needed. In other cases you could have a look at [reader writer locks](https://stackoverflow.com/questions/244316/reader-writer-locks-in-c). allow multiple parallel readers but synchronize on write. – Pepijn Kramer Jan 06 '23 at 08:58
  • I think without an atomic, strictly your code has undefined behaviour – Alan Birtles Jan 06 '23 at 09:18
  • Your code would be undefined behaviour, which is never a good thing. It may behave very differently, even on the same system, depending on which routes the compiler chose! Use the right tools for the job. At least atomic values, at best smart locks such as `unique_lock`. – SimonC Jan 06 '23 at 09:41
  • @PepijnKramer I am meaning to read and write at the same time, but there would be only one writer and one reader – user20943446 Jan 06 '23 at 20:47
  • Ok then you will have really have to protect your data. If you really want fine grained locking You could use a std::array>. If you have a vector then you need to protect that also with a mutex because it can reallocate when adding. Multithreading is no free lunch, there will be overhead (so it is important to know this overhead will not be offset by the speed you gain through multithreading) – Pepijn Kramer Jan 07 '23 at 06:20

1 Answers1

0

https://en.cppreference.com/w/cpp/atomic/memory_order says:

If one evaluation modifies a memory location, and the other reads or modifies the same memory location, and if at least one of the evaluations is not an atomic operation, the behavior of the program is undefined (the program has a data race) unless there exists a happens-before relationship between these two evaluations.

You will need at least one atomic variable or call to std::atomic_thread_fence.

And witout this if you wanted to do something similar to this:

extern int index;
extern int *array;

void try_to_read()
{
    // wait till filled
    while(index != -1);
    // do something with data[index]
}

Then that would not even be compiled as you would expect. Compilers will optimize out this while.

sklott
  • 2,634
  • 6
  • 17