Semaphore (programming)

A semaphore is a data structure, the " Reserve / Try " from an integer and use operations and " Share " is. It is particularly useful for managing limited ( countable ) resources that multiple processes or threads to access, such as producers and consumers. Unlike a lock or a mutex activity carrier, the "reserve" and "Share " need not be identical.

Operation

Most integer (counter) is initialized when the semaphore with the numerical value of the maximum available resources or the maximum number of processes that can use the resource simultaneously. A process that wants to access the resource, you must first operation " Reserve / Try " call, and then when he no longer needs the resource, the operation " Share ". For each reservation, the counter is decremented by 1, upon release he is again increased by 1. The meter shall not fall below 0: If a reservation is made at count 0, the reserving process waits until another process has enabled resources. There are also implementations that are negative. This can be shown how many processes are waiting for a release.

Semaphore can be used for programming with process synchronization, ie to the solution of tasks in which the parallel execution of multiple processes / threads requires a timing of designs. They are generally used to establish an order in a limited number of resources in the many threads to those scarce elements share (eg resource: " CPU Core ", number: 4). This can also be used for encapsulation of accesses to shared data ( resource: "Access to data ", number: always only one at a time). Also to communicate between threads semaphore can be used. Then usually serve as a counter for available information packets. Here, the semaphore is "0 packages available " started, and then counted up ( and back down to 0 ).

Origin of the name

The word goes back to the semaphore semaphore signals mechanical railway signals. The semaphore used therein indicate whether a train show a resource, so can drive on a track section or not.

Interactions parallel running processes

In the parallel or time-sharing execution of processes occur implicit or explicit interactions.

In implicit interactions a process is not aware that another process is affected by the execution of actions. This is for example the case when a process invokes a system service that the operating system can not be processed instantly completely because other processes have the necessary resources occupied. The process can only continue its actions further if the system service has been performed. Here, the process of interaction is visible as a blocking function call. Special precautions against blockage due to implicit interactions must and can not take a process.

Explicit interactions between processes are:

Both the Reserve and the Share must be atomic operations. Can not be satisfied a reservation, so they can simply block ( obtaining the resource via race condition among those waiting ), the semaphore queue run (typically blocking) or reject ( non-blocking). Of resources is often only one copy exists (so-called mutual exclusion ), the semaphore then causes a vote of the temporal execution of the process actions. In the case of a competition situation is achieved by somehow designed sequencing of execution ( the critical sections ) that the resource is not used by multiple processes arbitrarily changing. In the case of a cooperation situation corresponding sequencing is also achieved by the situation that the cooperation of the processes is given (eg, that a contractor does not already tried to start to edit something, even though the client has not yet given no order ).

Solution of Dijkstra

Semaphore as a mechanism for process synchronization Edsger W. Dijkstra were designed by and presented in 1965 in his article Cooperating sequential processes.

A semaphore is a data structure with initialization and use two operations. The data structure consists of a counter and a queue for the receiving process is blocked (in this case an example in C )

Struct semaphore {      int count;      Queue queue; / * Queue * /   }; Counter and queue are protected and can only be changed via the semaphore. The effect of the mobilization operation can be summarized as follows:

  • Semaphore regulate by counting interaction situations of processes
  • Semaphore realize a passive waiting of processes when a further execution can not be allowed

With the initialization of the counter to a non-negative value (≥ 0) and the queue typically is set to empty.

Void init ( semaphore & s, int v) {      s.zaehler = v;      s.queue.empty ();   } If a semaphore for the organization of competitive situations are used, is initialized to a positive value. A semaphore for a cooperation situation, however, is initialized to 0 ( see examples ).

Use operations were described by Dijkstra with P and V. These are initials of Dutch words or trunk words for prolaag and Verhoog. Further, common explanations are passeer, probeeren ( check German ) and vrijgeven, verhogen ( German ) increase. Programming interfaces use mnemonic names such as clearer wait, acquire or down for the P operation and signal, release, or post up for the V- operation.

A call to the P operation, the counter is decremented. If the counter is greater then 0, then the process continues its actions. However, the counter is smaller than 0, the control flow does not return from the operation. The calling process is blocked and queued in the queue of the semaphore. In a call to the operation of the V- counter is incremented. It is removed and deblocked, if the queue is not empty, a process from the queue. The deblocked process then continues its actions with those that follow the P- call that blocked the process. The illustrated here how the semaphore permits easy determination as to whether there are processes that are blocked on the semaphore: the Semaphorzähler is less than 0, it is still blocked processes. These processes called for the P- operation, when the counter was already less than or equal to 0. The review will be listed here in order to illustrate the effect of the V- operation on other processes explicitly. Concrete implementations can relocate a check for non- empty queue in the queuing method.

/ * Down () * /   void P ( semaphore s ) {     s.zaehler s.zaehler = - 1;     if ( s.zaehler <0)        selbst_blockieren ( s.queue ); / * Block the process, classification in queue * /   } / * Up () * /   void V ( semaphore s ) {     s.zaehler s.zaehler = 1;     if ( s.zaehler < = 0)        einen_entblocken ( s.queue ); / * Unblock a process from the queue * /   } Semaphore can take on a " 1" as the largest positive value their counter due to the initialization and use, including binary semaphore or mutex locks are often referred to. Semaphore whose counter can assume positive values ​​greater than "1" are called counting semaphores.

Both operations must be indivisible, atomic actions. This guarantees that, after the invocation of an operation of a semaphore no other process on the same semaphore can be accessed by modifying an operation call before the called first semaphore has been completed. The atomicity is necessary to organize the synchronization and avoid race conditions when executing the semaphore by parallel processes.

The above explanation of the operation is one of several possible. These differ by the order of testing for blocking / unblocking and surgery increment / decrement. In some representations of the counter does not accept negative values ​​. ( The counter value described above is obtained by subtracting from the Actual length of the queue. ) In this case, the term binary semaphore is then obvious. However, the effect of the operations processes is independent of the type of implementation. The above explanation has been given for a simple interpretation of the numerator of preference: If the counter is greater than 0, it indicates its value, how many processes can call the P operation even without blocking. If the count is negative, its absolute value indicates how many processes have called the P- operation and were blocked there.

Semaphore resolve the disadvantage of the active waiting other synchronization solutions such as special machine instructions or spinlocks because a process is blocked until the blocking reason is omitted. The definition does not specify which blocked process is taken in the performance of the V- operation of the queue. A semaphore which guarantees a real queue, first-served principle (English " first come, first served" ) is sometimes referred to as a strong semaphore. A weak semaphore however, does not guarantee the chronologically correct processing of the queue. For example, the deblocking of processes is subject to the priority instead of the blocking time of, for example, during real-time operation.

Application Examples

  • Use in competitive situations I In a critical section ka_A process A changes a data structure that uses the process with a process B. Process B changes the data structure in its critical section ka_B. A semaphore in exclusion function is used in order to achieve that the processes A and B are never simultaneously in their critical sections. For this, the semaphore is initialized to 1, so it is a binary semaphore is used:

Shared semaphore of A and B: mutex         Initialization: init ( mutex, 1 ) / * There is one resource copy "right to enter a critical section " (kA ) * /         Process A Process B            ......            P ( mutex ) P ( mutex ) / * try to reserve " entering law " ( blocking) * /            ka_A ka_B            V ( mutex ) V ( mutex ) / * release the " enter -right " * /            ...... Use in competitive situations II Need processes exclusively to each of a resource that is only available in a limited number available, so is achieved by means of a counting semaphore that a process is blocked when all the resources are in use. The semaphore is initialized with the number of available resources:

Semaphore for resource management: s_available         Initialization: init ( s_available, n)         process            ...            P ( s_available ) / * Display the usage wanting; " was reserved for me " wait until * /            ... / * Use of the resource * /            V ( s_available ) / * Display the usage statements to share * /            ... Use in cooperation situations A process contains a program section C_I, in which a data structure is initialized, which is then processed by process B in a program section C_V. Obviously C_I must be performed under all circumstances before C_V. There a semaphore is used in signaling function:

Shared semaphore of A and B: s_inform         Initialization: init ( s_inform, 0)         Process A Process B            ......            C_I P ( s_inform )            V ( s_inform ) C_V            ...... Process B tries to reserve, and must wait until process A s_inform ( " available 1 record " ) means release on 1 has counted.

Implementation

An implementation of the Semaphormechanismen is conceptually to settle in the operating system, because it needs to work closely with the management process. A realization of the indivisibility on mono-processor systems can then be done for example by means of interrupt lock. In the case of multi-processor systems, a bracketing of sequences of instructions by the semaphore spinlock is required. A realization by the operating system also allows multiple processes can share a semaphore with their actually disjoint address spaces.

Become a semaphore by a thread package that runs in the user address space ( user-level threads) available, then the realization of the indivisibility designed complex. You must take into account any interruptions and depends on which present information about user-level threads in the core.

Related Topics

  • Mutex - enable generic term for methods that mutual exclusion of data accesses.
  • Jacketing - the ability to bypass a blocking system call.
  • Bolt - variable - variant of the semaphore to more flexible implementation of a read- write lock.
722949
de