Processes are mutually exclusive with P and V Operations.
I. Critical resources
What is a critical resource:
At any time, only the resources used by one process are allowed as critical resources.
What is a critical section:
Access critical resourcesCodeSegment is the critical section.
For example:
Code segment 1
A = count;
A --;
Count =;
Code Segment 2
B = count;
B ++;
Count = B;
It is a critical zone, and count is a critical resource.
Access to critical resources must meet the following conditions:
Only one process can enter at a time and other processes can wait.
The entrant must exit within a limited period of time.
The waiting person should have the opportunity to enter.
Ii. semaphores
Semaphore structure model: (S, q)
In the 2.4.x kernel, the semaphore data structure is defined as (include/ASM/semaphore. h ):
Struct semaphore {
Atomic_t count;
Int sleepers;
Wait_queue_head_t wait;
# If waitqueue_debug
Long _ magic;
# Endif
};
Semaphore operation:
1) initialization
2) P operation
A) s --
B) if (S & lt; 0) sleep in Q queue
Enter else
3) V Operation
A) s ++
B) if (S & lt; = 0) Wake up a sleep process (waiting for a process in the queue to be asleep)
Else continue
The P operation can be understood as applying for resources, and the V operation can be understood as releasing resources. In the 2.4.x kernel semaphore structure, count indicates the Resource Count. If it is a positive number or 0, it indicates the number of available resources, -1 indicates that there are no idle resources and waiting processes. As for the number of waiting processes, the implementation depends on sleepers, which is complicated, but the advantage is that the up operation is very simple, add count to 1 in an atomic manner. If the value is less than or equal to 0, a process waits. Call _ up_wakeup () -- & gt; _ up (). Otherwise, a result is returned. In Linux, You can see (2.4.x kernel) ,__ down () and _ up () in arch/i386/kernel/semaphore. C ().
Semaphore implementation:
Use a simple implementation of Itron & lt; An Itron Implementation & gt; as an example. I roughly read the code. For the P/V Operations on semaphores (semaphore), there are counter control and waiting queue.
The semcb (semaphore control block) structure contains members such as ID, queue, and counter.
OS _acquiresemaphoretimeout ()
{...
Lock ()
Semcb-& gt; semcnt -- // counter --
If (semcb-& gt; semcnt & lt; 0)
{
Make_wait () // make current task in wait state
Queue_insert_tpri () // insert by priority to the semaphore's
// Wait queue, which is a circular queue
}
Unlock ()
...
}
OS _freesemaphore ()
{...
Lock ()
If (semcp-& gt; semcnt & lt; 0)
{
Wait_release_ OK ()
|
-& Gt; wait_release () // release a task from wait state
}
Semcb-& gt; semcnt ++ // counter ++
Unlock ()
...
}
Note: In the V operation, adding 1 to s first and then determining whether the value is less than or equal to 0 is equivalent to determining whether the value is less than 0 and then adding 1.
Note: In this implementation, the semcnt value not only indicates that the resource is idle or has a process waiting, but also its absolute value is meaningful. The negative value indicates the number of waiting processes, A positive or zero value indicates the number of idle resources.
Iii. Synchronization mutex Model
S = 1
A
P (S)
Critical Section
V (s)
B
P (S)
Critical Section
V (s)
Producer and consumer problems
(Generate the number calculated by the producer, which is printed by the consumer .)
One producer and one consumer, and the buffer Buf is 1
Two semaphore implementation models: Put = 1 get = 0
A
Computing x
P (Put)
Buf = x
V (get)
B
P (get)
Y = Buf
V (Put)
Print y
One producer has two consumers and the buffer Buf is 1 (two consumers print an odd number and an even number)
Three semaphore implementation models: Put = 1 getj = 0 Geto = 0
A
Computing x
P (Put)
Buf = x
If (X is odd)
V (getj)
Else
V (Geto)
B
P (getj)
Y = Buf
V (Put)
Print y
C
P (Geto)
Y = Buf
V (Put)
Print y
This model is intuitive, but three semaphores are used. After calculating X, determine its parity and then the different semaphores of "V.
If only two semaphores are used for implementation, the producer calculates X and then directly "v" A semaphores. After the two consumers take out the semaphores, the producer determines whether to print or not.
Two semaphore implementation models: Put = 1 get = 0
A
Computing x
P (Put)
Buf = x
V (get)
B
P (get)
Y = Buf}
If (Y is odd)
{
V (Put)
Print y
}
Else
V (get)
C
P (get)
Y = Buf
If (Y is even)
{
V (Put)
Print y
}
Else
V (get)
One producer and one consumer. The buffer Buf is M.
Two semaphore implementation models: Put = m get = 0
A
Computing x
P (Put)
Buf [T] = x
T = (++ t) % m
V (get)
B
P (get)
Y = Buf [k]
K = (++ K) % m
V (Put)
Print y
N producers and M consumers, and the buffer Buf is m
Four semaphore implementation models: Put = m get = 0 T = 1 K = 1
A
Computing x
P (Put)
P (t)
Buf [T] = x
T = (++ t) % m
V (t)
V (get)
B
P (get)
P (k)
Y = Buf [k]
K = (++ K) % m
V (k)
V (Put)
Print y
4. delete a semaphore
To delete a semaphore, the system should release some resources. If no process is waiting for this semaphore, the processing is relatively simple.
If a process is waiting for this semaphore and how to handle these processes, some people say kill, but one implementation I see is wake up.
In addition to the process, this waiting queue also needs to be released, otherwise it will cause memory leakage.
Not only is a semaphore deleted, but when a resource is deleted in the system, all tasks waiting for the queue are released.
OS _delflag -- |
OS _delmessagebuffer -- | -- & gt; call wait_delete (queue *) -- & gt; OS _delsemaphore -- |
While ()
{Wait_release ();...} // release all tasks blocked on specified wait queue
V. Origin
why did you beat such a thing. Because there is a self-implemented Itron-based OS that needs to be tested. I added a test case when testing its semaphore resources, that is, how the system will respond when a process is waiting for a semaphore to delete it. Based on this, the tester first introduced the semaphore and the synchronous mutex model. Then we roughly looked at the implementation of P/V Operations and semaphore deletion in Linux 2.4.x, Itron, and uClinux systems. I did not conduct in-depth research because of my busy work. I spent two hours to solve the bug and enter it. Then steedhorse helped with the check. After an hour of discussion, I changed some errors. Thank you.
I am not very clear about some issues. I hope you can discuss them later.