Mutual exclusion (Part 1)

The 10th Operating System Membership Meeting of the Year has begun!

The monthly meeting is designed to allow everyone to communicate with each other and solve recent problems at work to improve the efficiency of the entire computer system. Because computer hardware is developing rapidly, and the operating system is the middle layer that connects computer hardware and applications , if it stays on its own, it will soon be eliminated by the market, so every operating system member attaches great importance to monthly meetings.

This time, it is the two brothers, process and thread, that raise the question.

Standing in front of everyone, Thread seemed a little stage fright. He poked at the process and motioned for him to speak first. The process quickly sorted out his thoughts, straightened his body, and said, "The problem this time was found in a ticketing system. I drew the simple logic of this system, and you can talk while watching me."

"This booking system is divided into server and client. When the user establishes a connection with the server, the server will establish a new thread to provide services for the client. The booking logic is as follows:

From this logic diagram alone, there is no problem, but in practice, because there are often scenarios where multiple users rush to book a ticket at the same time, this method may go wrong. like this:

Before thread A determines the remaining tickets (assuming it is 1), but fails to book tickets successfully, thread B gets the information that the number of remaining tickets is 1, so B also thinks that the ticket can be booked, and finally causes a ticket to be sold for two share. "

The memory said sharply: "I think this is a conflict between the execution flows of several threads. Originally, after the ticket booking operation of one thread is completed, the other thread can query the remaining tickets. If the flow crossover is performed like this, there will definitely be other intentions. Unexpected question."

The process said with admiration: "Don't say it, what you said about memory is too reasonable. I have also encountered a similar situation. Last time I shared a part of the memory space with another process, but when using the same data, he It overwrites the data I just wrote, causing all my subsequent calculations to go wrong."

At this time, the disk expressed his opinion: "The problem of execution flow, it is the pot of the process scheduler at first sight, why do you have to drive people off the CPU when others execute key steps! If the scheduler waits for a while , isn't this problem solved?"

When the process scheduler heard this, he stood up angrily and said, "You, how can you slander someone's innocence out of thin air! It's not up to me to decide when to switch processes, okay? I'm responsible for selecting the CPU that should be used the most from the ready queue . It 's just processes . When I start scheduling, those processes have been taken down by the operating system."

The operating system added: "The scheduler is right, the timing of the scheduling is determined by the interrupt . It seems that this situation occurs when the process time slice is exhausted, the clock interrupt occurs, and then the CPU resources are preempted by other processes. ."

The disk heard it and said embarrassedly: "I'm sorry, I was too arbitrary just now. According to your opinion, when we execute this part of the code, can this problem be solved by masking the clock interrupt like this?"

The operating system shook its head: "The " interrupt disable " method does prevent the process from switching when this part of the code is running, but the clock interrupt is a very important function of mine , how can I just hand over control What about humans? What if some programmers want their code to fully occupy the CPU and not turn on the clock interrupt for me? It is impossible for me to hand over such important authority, I am responsible for the whole system. "

The memory side agrees: "In addition to this aspect, you must also know that it is now a multi-core era. Even if you disable the clock interrupt of this CPU, several other cores can still switch processes and then access the data. Disk ah , you obviously have so many files saved, how come you still know so little..."

Disk said angrily: "Don't look down on me, I'll find out if there is a way to solve this problem!"

After thinking about it for a long time, the CPU said: "Let me take a look, now our goal is to prevent two processes from executing this piece of code at the same time - let's call this piece of code a critical section , in other words, we need to Let the processes enter the critical section mutually exclusive . Then we " lock " this critical section ,"

"Locked? What does that mean?"

"Locking is a metaphor, in fact, " lock " is just a shared variable, we can make it have OPENand CLOSEthese two values. A process, such as A, before entering the critical section, first check whether the lock is in the OPENstate , and if so, change the lock to the CLOSEstate, so that when other processes enter the critical section, they will find that the lock is already CLOSEin the , so let them loop Wait until A is out of the critical section and then open the lock. "

The memory frowned and found that things are not so simple - if A finds that the lock is open, but switches to process B before A closes the lock, then B will also find that the lock is open, then B also will be able to enter the critical section !

Thinking of this, the memory tells the CPU the problem, but the CPU says it's not a problem for him.

It turns out that there is a hardware-supported instruction in the computer - TSL (test and set lock, test and lock), this instruction can ensure that the operation of reading and writing words is " inseparable ", that is, before the end of this instruction. , even other processors cannot access the memory word.

"The TSL instruction will read the memory word lock into a register, and then write a non-zero value to the corresponding memory address . Then we can use this instruction to improve the lock method just now, like this:

We let the process call before entering the critical section enter_region, and if the lock is already closed (shows that the lock is not 0), it will be called enter_regionin a loop until the lock is opened, and then enter the critical section. After exiting the critical section, call leave_regionto open the lock. Doesn't this solve your problem? "

Memory nodded and said, "This is really a good way to solve the mutual exclusion problem of critical sections."

However, the operating system is not very satisfied with this solution: "This solution requires busy waiting and wastes CPU resources. I think this TSL solution needs to be improved."

There was silence at this point—no one thought of a better solution, and the meeting seemed to freeze.

Who can think of a better solution?


Haha, I foreshadowed in the article, guess who found a better way?

Make up a link to the next article: Mutual exclusion (below)

If you think my writing is good, give it a like!

Disclaimer: Original article, unauthorized reproduction is prohibited

If this article is helpful to you, welcome to pay attention to the ravings of my public account tobe , and take you deep into the world of computers~ There are surprises in the background of the public account to reply to the keyword [computer]~

{{o.name}}
{{m.name}}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324133210&siteId=291194637