Introduction

You’ve probably heard of the resource dispute handling technique and Race-Condition fixes using mutex and semaphore, right? If you are not sure about it then read this article. Since this is an article in the form of love, I will go to explain, analyze, comment more than write example code and demo.

What is a resource dispute?

You’ve probably heard of the resource dispute handling technique and Race-Condition fixes using mutex and semaphore, right? If you are not sure about it then read this article. Since this is an article in the form of love, I will go to explain, analyze, comment more than write example code and demo.

– In programming, a resource can be a variable, a subroutine, a file, g, an address …

Why do you need to resolve resource disputes?

– Very simply, resource disputes cause our application, system to run wrong with design, or cause unexpected program crashes.

Race-Condition phenomenon

– If you do a reading online, the way to resolve resource disputes and race-condition is the same, making us mistakenly think the resource dispute and race-condition are the same definition, but they are not.

– Race-condition as in its literal sense is the phenomenon of racing conditions. It appeared in both electronics and programming.
This is an example.

– You have a total of 8 horses similar to 8 race horses having each of its own runs, these 8 horses have the same speed and run an equal distance eg 100 meters. Mr. Phat at the starting line was responsible for taking the arbitrary number of horses to run, and Mr. Dich at the finish line was responsible for counting the number of horses to the destination. Mr. Phat will choose from 0 to 8 horses to run and at the same time inform Mr. Dich that the horses have run.

– Mr. Dich does not know in advance how many horses will run, but knows for sure when the horses start to run and knows for sure that after 10 seconds these horses will reach their destination. Therefore, exactly 10 seconds after the departure, Mr. Dich went to count the horses. Everything is still going smoothly, Dich always counts the correct number of horses that Mr. Phat has run, until 1 this time, the number 4 horse is running when he stumbles on the ground and falls and gets up and finishes at 10,001 seconds. But, oh oh, at 10 seconds, Déd came to count the horses and only 5, while Mr. Phat was determined to have run 6.

Hình 1. mình họa

– Mr. Dich counts the horses at 10 seconds while the right moment that Mr. Dich should count is at 10,001 seconds is an example of race-condition. The event that the number 4 horse stumbles is called an uncontrollable event, maybe the next time the 3rd horse stumbles in the air and falls for 0.02 seconds, then Mr. Destination reads at 10,001 seconds.

– The simple horse count example above is also described for parallel data transmission, for example you need to transmit 8 bits on 8 separate lines. After recording the 0.1 states on the Output pin, we output a signal on a pin called the Clock Pin. At this time, the receiver (Mr. Dich) also has 8 I / O pins to record the status of the transmitter (Mr. Phat) and immediately after receiving the signal from the Clock Pin, the receiver records the status of the 8 Input pin. . If there is a delay in updating the 0/1 state of 1 of the 8 pins, the receiver will record the wrong state with the transmitter and the transmission is considered to fail.

This parallel transmission model is often applied to high-speed transmission needs, for example, RAM. When looking at the layouts on the boards you see the curving lines. The purpose of this is to make the length of the roads connecting from Mr. Phat to Mr. Dich equal with the goal of having happiness and suffering and suffering.

– Something is wrong, right is there is fast with fast, with slow. You understand what you mean, right, do not write again to move on to another idea.

Race-condition in Software.

– The above paragraph is about the general meaning for us to have an overview, but nowadays searching online, the Western guys just take the example race-condition between two threads, we also find it difficult to imagine the overall problem. What is shouting.

Then going back to programming, race conditions occur when multithreaded programming when different threads write / read to common variables. As for different processes, it is possible to read together when it comes to 1 file, shared memory (shared – memory). Shared memory is extremely good, I will share it in another article.

– To make it easy to imagine me writing this code.

Hình 2. Code ví dụ

The idea is that I will create 10000 threads, and in each thread will for-loop to increment 1000 units.
The final result will logically be 10,000,000. But the results were less than 10,000,000 and varied with each run.

Hình 3. Kết quả khác nhau trên mỗi lần chạy

So what happened?

– If we look at the code we see 10000 threads are writing data to the common variable val. Somewhere on the internet, there will be those definitions.

– So to find the root cause, let’s analyze it, only the command val + = 1 has interaction with the variable, most likely there is something mysterious behind. But this command is to increase val by 1 unit, what’s the mystery about? As for web model, this command is just font-end for developers, behind the back-end, who knows what the compiler is doing behind. To see what the compilers do in the background, I decide what the code to execute the build images is.

– I use this page https://godbolt.org to see the assembly code of the command val + = 1
– There is actually a difference on different CPU architectures, for example with an Intel CPU the val + = 1 command is translated into the following 3 execution instructions:

– The three instructions above are as follows: Load the value in RAM into the memory on the CPU, increase the value on the CPU by 1 unit, and write the value from the CPU to RAM. Here it is Boom, if unfortunately the 2 threads only deviate exactly 1.2 code like this.

– Thread 2 should have waited for thread 1 to finish transferring data from the CPU to RAM before doing its job.
Also interesting is that different CPU architectures have different “back-end” codes. For example, on ARM there are up to 5 commands, meaning the chance of a race-condition occurring is higher.

How to resolve Race-Condition?

Going back to the horse example above, race-condition occurs because the horse-count occurs when the running is not completely finished. For the sake of simplicity we need some information to ensure that the horse’s run has been completed before starting the horse count.

– At this point, we need to reiterate the dispute over resources a bit. As in the Audio Output example, the two Threads that open the music can use a flag variable to see the value if the flag equals 1 then thread A uses Audio Output, if the flag is 2 then Thread B uses Audio Output.

– Sounds fine, but it got into the race-condition error of the flag variable. Therefore, this flag variable cannot be used to evaluate the state, now Linux introduces mutex and semaphore techniques to help ensure the user (ie Linux is the one who wrote the code) writing / reading on the mutex / semaphore is unique and always successful.

– That is why mutex / semaphore solved race-condition for the flag variable and thereby resolves the resource dispute problem. In addition, to avoid race-condition for important variables, the code brothers use mutex / semaphore to solve race-ccondition for the variable. That is why the first part of me to discuss resource disputes and race-condition is different, but we can use the same mutex and semaphore solution to solve the confusion between these two guys.

– Using mutex and semaphore are common ways used today, you can refer for yourself. Here I introduce a little different, look where val + = 1 we see that race-condition appears because the compiler compiles into many different codes.

Atomic Operation

– From C11, Compiler provides a variable type that supports Atomic Operation on it, Atomic is unique, Operation is action + – * /. That means if declaring a variable that supports atomic operation, the command Val + = 1 will be completely executed in a single CPU code and there is no race-condition on val …


– This is the compiler standard library, very simple to declare and use, just include the library stdatomic.h and edit the variable int val to atomic_int val.

– Val’s return result is correct

Summary

– Handling resource disputes and Race-Condition by synchronizing between threads / processes, although it helps us to solve the problem, but it reduces the performance of the program. That means your system has many interdependencies.

– Obviously we can see if there is a resource dispute, when thread A runs, thread B waits. This waiting inadvertently turns our application from a parallel system to a sequential system.

Share on facebook
Share on twitter
Share on linkedin