What is meant by a "thread safe" object?

I used a shared queue in a C # collection, and everyone says it is better to use the System.Collection.Generic.Queue object due to thread safety.

Please indicate the correct decision to use the Queue object and how is it safe in the stream?

+6
collections multithreading c #
source share
3 answers

“Thread safe” is a slightly unfortunate term because it does not really have a clear definition. Basically, this means that certain operations on an object are guaranteed to behave reasonably when the object is managed through multiple threads.

Consider the simplest example: a counter. Suppose you have two threads that increment a counter. If the sequence of events goes:

  • Stream one is read from the counter, gets zero.
  • To enter two readings from the counter, gets zero.
  • Stream one increases zero, writes one for the fight.
  • Enter two increments of zero, writes one for the fight.

Then notice how the counter “lost” one of the increments. Simple increment operations on counters are not thread safe; to make them thread safe, you can use locks or InterlockedIncrement.

Similar to the queue. Non-threadafe-queues can "lose" queues in the same way as non-threadafe queues can lose increments. Worse, non-thread-safe queues can even trash or create crazy results if you use them in a multi-threaded scenario incorrectly.

The difficulty with thread safety is that it is not clearly defined. Does this mean that it doesn’t fail? Does this mean that reasonable results will be obtained? For example, suppose you have a threadafe collection. Is this code correct?

if (!collection.IsEmpty) Console.WriteLine(collection[0]); 

Not. Even if the collection is "streaming", this does not mean that this code is correct; another thread could make the collection empty after checking, but before writing, and therefore this code may crash even if the object is supposedly “thread safe”. In fact, determining that each appropriate combination of operations is thread safe is an extremely complex problem.

Now, to come to your real situation: anyone who tells you “you should use the Queue class is better because it is thread safe” probably does not have a clear idea of ​​what they are talking about. First, the queue is not thread safe. Secondly, regardless of whether Queise is thread safe or not, it doesn’t matter if you use only an object in a single thread! If you have a collection that will be accessed by several threads, then, as I indicated in my example above, you have to solve a very difficult problem, regardless of whether the collection itself is "thread safe". You must determine that each combination of operations that you perform in the collection is also thread safe. This is a very difficult problem, and if this is the one you are facing, then you should use the services of an expert on this complex topic.

+25
source share

A type that is thread safe can be safely accessed from multiple threads without regard to concurrency. This usually means that the type is read-only.

Interestingly, Queue<T> not thread safe - it can support simultaneous reads until the queue changes, but this is not the same as thread safety.

To think about thread safety, think about what happens if two threads access Queue<T> and a third thread comes in and starts adding or removing Queue<T> from this. Since this type does not limit this behavior, it is not thread safe.

+5
source share

When working with a multi-threaded process, you usually have to deal with concurrency issues. The term "concurrency issues" refers to problems that are specifically introduced by the ability to alternate commands from two different execution contexts on a resource shared by both. Here, in terms of thread safety, execution contexts are two threads within a process; however, in related matters, they may be processes.

In order to ensure two goals, measures to ensure thread safety are primarily applied. Firstly, it is necessary to restore determinism as to what will happen if the contextual switch of flows (which is otherwise controlled by the OS and, therefore, is mainly non-deterministic in programs at the user level) in order to prevent the execution of some tasks in part or two contexts, one and the same place in memory one by one. Most measures simply use a bit of hardware test-and-set , etc., as well as the software level of the synchronization construct , to make all other execution contexts stay away from the data type, while the other does the work, which should not be interrupted.

Typically, read-only objects are thread safe. Many objects that are not readable can access data (read-only) with multiple threads without problems if the object does not change in the middle. But this is not thread safety. Thread safety is when all kinds of actions are performed with a data type to prevent any changes in it in a single thread from data corruption or deadlock even when working with many concurrent reads and writes.

+1
source share

All Articles