Consider the following solution to the producer-consumer synchronization problem. The shared buffer size is N. Three semaphores *empty, full* and *mutex* are defined with respective initial values of 0, N and 1. Semaphore *empty* denotes the number of available slots in the buffer, for the consumer to read from. Semaphore *full* denotes the number of available slots in the buffer, for the producer to write to. The placeholder variables, denoted by P, Q, R and S, in the code below can be assigned either *empty* or *full*. The valid semaphore operations are: *wait()* and *sigmal()*.

Which one of the following assignments to P, Q, R and S will yield the correct solution?

A |
P: full, Q: full, R: empty, S: empty |

B |
P: empty, Q: empty, R: full, S: full |

C |
P: full, Q: empty, R: empty, S: full |

D |
P: empty, Q: full, R: full, S: empty |

P=full, Q=empty, R=empty, S=full

Initial: mutex = 1

empty = 0

full = N

------------------------------------------------------

Given,

Empty = 0

Full = N

Mutex = 1

Since value of *empty* semaphore is 0, so you can not wait *empty* semaphore in first attempt.

**Note – ***empty* semaphore denotes the number of filled slots, so producer process must deal with *empty* and mutex semaphores. *full* semaphore denotes the number of empty slots so consumer process must deal with *full* and mutex semaphores.

Option (A) causes starvation.

OPtion (B) causes starvation.

Option (D) since number of filled slots are 0 initially denoted by *empty* semaphore, so consumer process can not consume. So, this implementation is wrong.

Only P: *empty*, Q: *full*, R: *full*, S: *empty* is correct order to ensure deadlock-free and starvation free implementation.