Mutual exclusion (below)

The link to the previous article is here: Mutual exclusion (Part 1)

"I found a good way!"

Unexpectedly, the speaker turned out to be a disk!

The process scheduler said shyly: "Do you have a method? Let's forget it. I'm afraid that the operating system will be messed up with your method."

Disk said aggrieved: "Isn't it just that I wronged you just now, what are you doing so stingy! Besides, I didn't come up with this method, I found it from the file."

The operating system raised its eyebrows: "Oh? What file did you find, so that everyone can take a look?"

The disk hummed, and the file was quickly pulled out.

"Dangdangdang~ This is the thesis of the master Dijkstra , he introduced a new variable type - semaphore (semaphore). Then also set two operations for the semaphore, P(proberen, detection) and V(verhogen, increment) ."

"To be clear, what is the usage of semaphore?" Process asked eagerly.

"Don't worry, let me read on... Dijkstra suggested that the Poperation is to check whether the semaphore is positive, and if not, block the calling process. The Voperation can wake up a blocked process and let it resume execution . Specifically, this is: "

// S 为信号量
P(s):
{
S = S - 1
if (S < 0)
	{
		调用该 P 操作的进程阻塞,并插入相应的阻塞队列;
	}
}
// S 为信号量
V(s):
{
S = S + 1
if (S <= 0)
	{
		从等待信号量 S 的阻塞队列里唤醒一个进程;
	}
}

Memory carefully looked at the code and said, "This implementation also requires atomic operations . Dijkstra's method is very interesting."

The process is circled: "Why can't I understand it at all? Please tell me about the memory."

"Okay, I'll use the simplest set of threads as an example:

// 线程 A,B,C , S = 1
...
P(S) 		//S = S - 1  若 S < 0 ,阻塞等待
购票操作
V(S)		//S = S + 1  若 S <= 0, 表明有线程阻塞了,得唤醒其中一个 
...

The "ticket operation" here is the critical section we want to protect, and we want to ensure that only one thread can enter at a time. Then we set Sthe initial value 1of . When thread A calls for the first P(S)time , Sthe value of , becomes 0, and A successfully enters the critical section. Before A exits the critical section, if thread B is called P(S), S becomes -1, and S < 0the judgment condition is satisfied, and thread B is blocked. V(S)After A calls , Sthe value becomes again 0, and if it is satisfied S <= 0, thread B will be woken up, and B will be able to enter the critical section. "

The process suddenly realized: "So it is, it looks similar to the binary lock , but you don't have to wait ."

Memory smiled mysteriously: "The semaphore can do more than that . Think about it, what would happen if I set the initial value of S to 2?"

"Two threads can access the critical section at a time!" The process responded much faster this time: "That is to say , the initial value of S can control how many threads enter the critical section , which is amazing!"

tobe Note: From the value of the semaphore, you can see how many processes can enter the critical section . If it is negative, it means that x processes are blocked because of calling P(S).

"Yes, so the semaphore is a very flexible concurrency mechanism. And the semaphore has another great use:

Do you see what's so special about these two processes? "

"emmmm, well, the Voperation actually placed Pin front of the operation, and the semaphore of the two operations is not the same ."

"Yes, using a semaphore like this allows two processes to synchronize . Look, if P1 runs to it P(S1), will it block?"

The process took a serious look and said, "Yes, the initial value of S1 is 0, and P1 must stop at this sentence. Let me see, if P1 wants to continue to run, it has to wait for P2 to call V(S1)to wake him up ."

"Yes, this is synchronization - the fast P1 must stop here and wait for P2 to reach the specified position. The order of execution of the two processes is like this:

That is to say, the xfinal value must be 30 , not 20. With the help of the semaphore, the two processes are synchronized . "

The process sincerely sighed: "The semaphore is too powerful! Let's use the semaphore to solve the problem of mutual exclusion in the future!"


tobe Note: The two main mechanisms of semaphore and mutex (that is, binary lock) are provided in Linux to achieve mutual exclusion, but the semaphore function of Linux is much more complicated than that described in the article, "UNIX Environment Advanced The book "Programming" wrote that "...three characteristics cause this unnecessary complexity." For general mutex operations, it is recommended to use mutex locks (of course, blocking rather than busy waiting). Slightly more complex locks and "read-write locks", I will talk about it later~

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

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=324225660&siteId=291194637