1

I have several threads that write data to the same buffer at the same time, but each one of them is writing to another range of indices in this buffer.

For example Thread1 is writing data only to indices 0-1000, Thread2 write only to indices 1001-2000, and Thread3 is writing only to indices 2001-3000.

Should I protect this buffer by using a lock method? Or is it a threads safe?

Thanks.

Editing:

It’s an int array:

int[] myArray = new int[3001];

Robert
  • 13
  • 5

1 Answers1

0

Yes, writing to a shared array from multiple threads in parallel, where each thread is writing to an exclusive part of the array, is thread-safe. This means that the array will not get corrupted during the write operation, and the written data will be preserved correctly (they will not get torn).

After the completion of the parallel writing operation it might be needed to add an explicit memory barrier, so that the data in the array are visible from the thread(s) that are going to read it. In general this is not needed, because the .NET infrastructure adds implicit memory barriers when various threading operations are started or completed. You can find a non-exhaustive list of these operations here: Memory barrier generators. I am mentioning this nuance because you have not provided any information about how you intend to read the array, after the writing phase has completed.

Theodor Zoulias
  • 34,835
  • 7
  • 69
  • 104
  • HI, in the method that start the threads using: threadName.Start(), I’m using threadName.Join() to wait for all the threads to finish, and then in the same method, and also from other methods (for example inside a button click event) I’m reading the buffer in the regular way: int getResult = myArray[i]; inside a loop, should it be a problem? – Robert Jul 14 '22 at 00:07
  • @Robert it might be a problem. I am not an expert in lock-free multithreading, so I can't tell you definitely that it's a problem, but neither I can tell you that it's not. If I were in your shoes I would take a more defensive stance (the `myArray` being a `volatile` field, assigned after the `Join`s). Unless I knew for sure that all threads that are going to read the array will be created **after** all writers have `Join`ed. The thread that invoked the `Join` of the writers can also safely read the array afterwards. – Theodor Zoulias Jul 14 '22 at 06:12
  • I still don’t understand. If I’m doing the reading from the buffet *After* all the threads finished their Join, then how can there be a problem? Are you saying that after the Join command has finished the thread may still be writing to the buffer? How can it be? – Robert Jul 14 '22 at 12:15
  • @Robert if you have time please check out this article by Igor Ostrovsky: [The C# Memory Model in Theory and Practice](https://learn.microsoft.com/en-us/archive/msdn-magazine/2012/december/csharp-the-csharp-memory-model-in-theory-and-practice). If you are going to practice lock-free multithreading, you should be aware of the pitfalls, and how you can avoid them. Lock-free multithreading is not easy, assuming of course that you value the correctness of your program, and that you don't want to leave anything to chance. – Theodor Zoulias Jul 14 '22 at 12:40
  • Looks very interesting I'll read it later, where is part 2 of the article? – Robert Jul 14 '22 at 13:34
  • @Robert here it is: [The C# Memory Model in Theory and Practice, Part 2](https://learn.microsoft.com/en-us/archive/msdn-magazine/2013/january/csharp-the-csharp-memory-model-in-theory-and-practice-part-2) – Theodor Zoulias Jul 14 '22 at 13:35
  • 1
    OK I found it in Google, thanks! – Robert Jul 14 '22 at 13:35