we are now able to express the buffer module in form that functions properly when used by individualconcurrent processesmodule bufferimport signalsconst (*buffer size*var ninoutintegernonfullsignals signal(* *nonemptysignals signal(* *bufarray of charprocedure deposit (xchar)begin if then signals wait(nonfullendinc( )buf[in:xin :(in mod nif then signals send(nonemptyend end depositprocedure fetch (var xchar)begin if then signals wait(nonemptyenddec( ) :buf[out]out :(out mod nif - then signals send(nonfullend end fetchbegin : in : out : signals init(nonfull)signals init(nonemptyend buffer an additional caveat must be madehowever the scheme fails miserablyif by coincidence both consumer and producer (or two producers or two consumersfetch the counter value simultaneously for updating unpredictablyits resulting value will be either + or - but not it is indeed necessary to protect the processes from dangerous interference in generalall operations that alter the values of shared variables constitute potential pitfalls sufficient (but not always necessarycondition is that all shared variables be declared local to module whose procedures are guaranteed to be executed under mutual exclusion such module is called monitor [ - the mutual exclusion provision guarantees that at any time at most one process is actively engaged in executing procedure of the monitor should another process be calling procedure of the (samemonitorit will automatically be delayed until the first process has terminated its procedure note by actively engaged is meant that process execute statement other than wait statement at last we return now to the problem where the producer or the consumer (or bothrequire the data to be available in certain block size the following module is variant of the one previously shownassuming block size of np data elements for the producerand of nc elements for the consumer in these casesthe buffer size is usually chosen as common multiple of np and nc in order to emphasise that symmetry between the operations of fetching and depositing datathe single counter is now represented by two countersnamely ne and nf they specify the numbers of empty and filled buffer slots respectively when the consumer is idlenf indicates the number of elements needed for the consumer to proceedand when the producer is waitingne specifies the number of elements needed for the producer to resume (therefore ne nf does not always hold module bufferimport signalsconst np (*size of producer block*