1. Problem definitionSome processes produce data, other processes consume data, and they pass data through a first-in, first-out queue of size n. When the queue is full, the producer blocks, and when the queue is empty, the consumer blocks. This scenario is quite common, such as media flow processing.
2. PV Primitives
PV Primitive, the concept of the proposed person is Henan (Netherlands) scientist Dijkstra, the master also proposed the diagram of the Dijkstra shortest path algorithm. The meaning of the primitive is atomic operation, that is, the operation cannot be split and cannot be interrupted. The PV primitive is used to manipulate the semaphore, generally speaking, p operation to reduce the amount of signal, v operation to increase the amount of signal, to be precise, look at the pseudo-code:
Procedure P (var s:samephore); { s.value=s.value-1; if (s.value<0) asleep (s.queue);} Procedure V (var s:samephore); { s.value=s.value+1; if (s.value<=0) wakeup (s.queue);}
Here S is the semaphore (Samephore), s.queue refers to the blocking process queue of S, which is also a first in, first out queue. Asleep (s.queue) means putting the process into the queue, wakeup (s.queue) means waking up a process that is located in the queue header, called Wake-up, which is the ready queue of the operating system.
3. Problem SolvingA perfect solution to producer consumer problems requires three semaphores: Fullcount,emptycount and Usequeue. As the name implies, fullcount means that the number of elements in the queue, emptycount means the number of slots in the queue, usequeue means that there is currently no process in the access queue. When running, Emptycount is smaller than the number of slots in the queue, such as when many producers are simultaneously waiting for usequeue, and Fullcount is smaller than the number of elements in the queue. For example, many consumers are waiting for usequeue at the same time------as if something is still in your warehouse and you have already sold it out. So Fullcount+emptycount <= N, however, when both the producer process and the consumer process have only one case, Fullcount+emptycount = = N. Note that the usequeue here is a semaphore with a value of 0 or 1, also known as a mutex semaphore, or mutex. Initialize Fullcount.value to 0,emptycount.value for N,usequeue.value to 1, then:
<strong>produce</strong>: p (emptycount) P (usequeue) putitemintoqueue (item) V ( Usequeue) V (FullCount)
<strong>consume</strong>: p (fullCount) P (usequeue) item←getitemfromqueue () V ( Usequeue) V (Emptycount)
4. Example
Audiotrack and Audioflinger data exchange in Android is a simplified version of the producer consumer problem, said it simplifies, because the first producers, consumers have only one, followed by the sharing of data only one buffer, that is, the queue of n== 1, every time the producers try to fill the buffer, consumers are trying to make buffer consumption clean. So, just need a usequeuewill be able to meet the demand! This signal volume isaudio_track_cblk_tin the definition, this is a ring buffer, the loop of writing and reading, by the way, ring buffer key is the record to read and write the location, according to these, you can also get the buffer is empty or full. in audio_track_cblk_t, there is a volatile int32_t
Mfutex, which is the key to producer consumer PV operations, and the comments in the code are: event Flag:down (P) by client, Up (V) by server or binderdied () or interrupt (). The corresponding PV operation is __FUTEX_SYSCALL4, similar to wait, and __futex_syscall3, similar to signal. Both of these implement blocking and awakening of the process. In this simplified model, Audiotrack is the producer, each time it is filled with buffer, then sleep, and wakeup the consumer, Audioflinger is the consumer, it reads empty buffer every time, then sleep, and wakeup producer.
Producer Consumer Issues