having hard time understanding one issue in consumer producer problem - c

I am having really hard time understanding one issue in consumer producer problem for example in the below image which is about the simple structure of consumer:
My big problem is that in wait(mutex) and signal(mutex) the parameter mutex is the same for both so it makes sense that signal(mutex) wake up wait(mutex) process if it is blocked but in wait(full) and signal(empty) they pass different parameters so how signal(empty) can wake up wait(full)??????(it is noteworthy that we assume both full and empty are of type semaphore)
here is some more information that may help:
also the code for producer is:

The mutex semaphore handles avoidance of mutual access to some shared resource, the full and empty semaphores handle when producer and when consumer is allowed to run. It all depends on the setup of the semaphores but basically full should be set up to block on the first wait of the consumer, empty should be available on first wait in consumer.
The producer will then handle data and post on the full semaphore, which in turn will unblock the consumer task. Consumer will block on the next empty wait until producer posts the empty semaphore and so on until infinity or program end.

Any producer/consumer solution uses a buffer. Practical buffer implementations need to deal with the buffer having a finite size. It thus needs to solve two synchronization problems. One is the obvious one, the consumer needs to be blocked when the buffer is empty and woken up again when an item enters the buffer. The less obvious one is that producer needs to be blocked when the buffer is filled to capacity, unblocked when a consumer removes an item.
Two very distinct blocking operations that affect different pieces of code. It thus requires two semaphores.

This concept is purely based on synchronization. Note two important things:
1. About full and empty:
Producer can not produce if the buffer is full and the consumer can not consume if the buffer is empty. So, semaphore full and empty are used only to check this requirement. Please, refer to your text, the initial value for empty is n(size of buffer) and initial value of full is 0(no item for consumer yet).
Step I. Producer has wait(empty) to check if the buffer has space(only then produce).
Step II. It has signal(full) to confirm that it has successfully produced one more item. Consumer can consume it now.
Step III. Consumer has wait(full) to check if it can consume something or not as whenever producer will produce an item, he will confirm(through Step II).
Step IV. Consumer has signal(empty) to confirm that it has consumed one time and so, the buffer space is free.(again Step I).
2.About mutex: The mutex variable is only to ensure that at one time,only one process accesses the buffer. That's why Producer and Consumer both have wait(mutex) and signal(mutex). Whenever any process(be it producer or consumer) accesses buffer, it acquires mutex and when it leaves buffer, it releases mutex.

Related

does semaphore preserve wait order [duplicate]

I have created a program in C that creates 2 buffers. The buffer indices hold single characters, 'A' or 'b' etc... In order to learn more about multithreading, I created a set of semaphores based on the producer/consumer problem to produce characters and consume characters from the buffers. I have 3 producer threads for each buffer and 10 consumer threads. The consumers take one item from each buffer, then report it (freeing the memory of the consumed item also). Now, from what I've read, sem_wait() is supposed to signal the "longest waiting thread" when it comes out of a blocking state (I read this in a book and in an online POSIX library).
Now, is this actually true?
The application I have made should have both consumers and producers waiting at the same sem_wait() gate, but the producers get into the critical section more than double the time of any consumer. The consumers do have an extra semaphore to wait for, but that shouldn't make that huge of a difference. I can't seem to figure out why it's happening, so I'm hoping someone else does. If I sleep(1) on the producer threads, the consumers get in just fine and the buffers hover around 0 items...like I would think would happen otherwise.
Also, should thread creation order play any role in how I structure the program for fairness?
IE, produce one of each type in a round robin fashion until everyone is created and running.
Are there any methods anyone can describe to me to institute a more fair system of thread access? I've read that creating a FIFO queue system might be one solution, where the longest waiting thread has the highest priority (which is what I thought sem_wait() would do anyways).
Just wondering what methods are out there for both rudimentary and higher level threading.
The POSIX standard actually says that "the highest priority thread that has been waiting the longest shall be unblocked" only when the SCHED_FIFO or SCHED_RR scheduling policy applies to the blocked thread.
If you're not using one of those two realtime scheduling policies, then the semaphore does not have to be "fair".

producer consumer concurrency without waiting POSIX

I have a certain resource and two threads one is producer and the other one is consumer.
The producer update the resource every time interval and the update takes some time and I don't want the consumer to wait. I want his instead to work with the old values of the resource while the producer update.
How do I synchronize the two threads without putting the consumer to wait
You can have an atomic pointer through which the consumer reads what the producer produced. Once the producer generated new data, change the value of the atomic pointer to point to that new data instead.
The shared resource is going to have to be locked while it's being updated/read from. I guess the consumer could copy the resource into a buffer of its own? Or would that take just as long?

about synchronization with using multiple semaphores

hi there i'm working on an assignment about using POSIX threads with multi semaphores. the brief explanation of assignment is: there are 4 various data packets (char/video/audio/image), each of them carried by a different thread and also we have a shared buffer. maximum threads can work on system will be maintained by the user as an input. for example; if user enters 10 then maximum 10 thread could be created to transmit data packets over a buffer in a given time. now the confusing part for me is, this buffer can contains limited packets instantly. (for example it can contain maximum 10 char packets and 20 video packets etc.) so we have to have different semaphores for each data type. the issue i know how to control the buffer size with semaphore which is very simple, but cant set the correct idea of using semaphores of packets'. even i tried some different methods i always faced with deadlock errors. here is my pseudocode to understand more clearly of my program.
define struct packege
define semaphore list
main
initialize variables and semaphores
while threadCounter is less than MaxThreadNumber
switch(random)
case 0: create a character package
create a thread to insert the package in buffer
case 1: create a video package
create a thread to insert the package in buffer
case 2: create an image package
create a thread to insert the package in buffer
case 3: create an audio package
create a thread to insert the package in buffer
increment threadCounter by one
end of while
create only one thread which will make the dequeue operation
end of main
producer function
for i->0 to size_of_package
sem_wait(empty_buffer) // decrement empty_buffer semaphore by size of package
lock_mutex
insert item into queueu
decrement counter of the buffer by size of package
unlock_mutex
for i->0 to size_of_package
sem_post(full_buffer) // increment full_buffer semaphore by size of package
end of producer function
consumer function
while TRUE // Loops forever
lock_mutex
if queue is not empty
dequeue
increment counter of the buffer size of package
unlock_mutex
for i->0 to size_of_package // The reason why i making the sem_wait operation here is i cant make the dequeue in outer region of mutex.
sem_wait(full_buffer)
for i->0 to size_of_package
sem_post(empty_buffer)
end of consumer function
with this implementation programe works correctly. but i couldnt use semaphores properly which belongs to threads of packages. i can listen every recommandation and will be appreciated for every answer.
This is not how semaphores are used. The buffer's control variables/structures should count how many messages are contained in the buffer and of what types. The mutex protects the buffer and its control variables/structures against concurrent access by different threads. A semaphore, if used, just signals the state of the buffer to the consumer and has no connection to the sizes of the packets; it certainly doesn't get incremented by the size of the packet!
You would be better advised to use pthread condition variables instead of semaphores. These are used in connection with the pthread mutex to guarantee race-free signalling between threads. The producer loop does this:
locks the mutex,
modifies the buffer etc to add new packet(s),
signals the condition variable, and
unlocks the mutex.
The consumer loop does this:
locks the mutex,
processes all buffered data,
waits for the condition variable.
Read up on pthread_cond_init, pthread_cond_signal and pthread_cond_wait.
Since it's an assignment, you probably don't need to have real packets data read and write, but just simulate their handling.
In that case, the problem boils down to how to effectively block the producer threads when they reach the limit of packet they can write in the buffer. At the moment, you are using the semaphore to count the individual elements of a packet written in the buffer, as far as I understand.
Imagine that your writes in the buffer are atomic, and that you just want to count the packets, not the packet elements. Each time a producer writes a packet, it must signal it to the consumer, with the appropriate semaphore, and each time the consumer reads a packet, it must signal it to the appropriate producer.
Let me highlight a few other points:
The important property of a semaphore is that it will block when it reaches zero. For instance, if its initial value is 10, after 10 successive sem_get, the 11th will block.
You have 4 types of packets, each with a different threshold on the number that can be written in the buffer.
As I said, the producer must signal that it wrote a packet, but it must also be stopped once it reaches the threshold. To achieve that, you make it acquire the semaphore each time it posts a new packet, with sem_get. And you have the consumer do a sem_post each time it read a packet, the reverse of what you did with your single semaphore version. However, since you want the producer stop at the threshold, you initialize the semaphore with a capacity of N - 1, N being the threshold. Note that you have to signal that a new packet is available after you wrote it in the buffer, otherwise the consumer might block the buffer.
producer<type> function
write_packet() // put the packet in the buffer
sem_wait(type) // signal a new packet is available
// (if there's not enough space for another packet, the producer will block here)
end producer<type> function
consumer function
while TRUE // Loops forever
switch packet_available() // look if there's a new packet available
case video:
read_packet<video>()
sem_post(video)
(...)
default: // no packet available, just wait a little
sleep()
end if
end while
You still need to define the packet_read, packet_write, and packet_available functions, probably using a mutex to limit access to the buffer.

Thread-safe ring buffer for producers-consumer in C

In C, I have several threads producing long values, and one thread consuming them. Therefore I need a buffer of a fixed size implemented in a similar fashion to i.e. the Wikipedia implementation, and methods that access it in a thread-safe manner.
On a general level, the following should hold:
When adding to a full buffer, the thread should be blocked (no overwriting old values).
The consumer thread should be blocked until the buffer is full - it's job has a high constant cost, and should do as much work as possible. (Does this call for a double-buffered solution?)
I would like to use a tried implementation, preferably from a library. Any ideas?
Motivation & explanation:
I am writing JNI code dealing with deleting global references kept as tags in heap objects.
When a ObjectFree JVMTI event occurs, I get a long tag representing a global reference I need to free using DeleteGlobalRef. For this, I need a JNIEnv reference - and getting it is really costly, so I want to buffer the requests and remove as many as possible at once.
There might be many threads receiving the ObjectFree event, and there will be one thread (mine) doing the reference deletion.
You can use a single buffer, with a mutex when accessed. You'll need to keep track of how many elements are used. For "signaling", you can use condition variables. One that is triggered by the producer threads whenever they place data in the queue; this releases the consumer thread to process the queue until empty. Another that is triggered by the consumer thread when it has emptied the queue; this signals any blocked producer threads to fill the queue. For the consumer, I recommend locking the queue and taking out as much as possible before releasing the lock (to avoid too many locks), especially since the dequeue operation is simple and fast.
Update
A few useful links:
* Wikipedia explanation
* POSIX Threads
* MSDN
Two possibilities:
a) malloc() a *Buffer struct with an array to hold some longs and an index - no locking required. Have each producer thread malloc its own *Buffer and start loading it up. When a producer thread fills the last array position, queue the *Buffer to the consumer thread on a producer-consumer queue and immediately malloc() a new *Buffer. The consumer gets the *Buffers and processes them and then free()s them, (or queues them off somewhere else, or pushes them back onto a pool for re-use by producers). This avoids any locks on the buffers themselves, leaving only the lock on the P-C queue. The snag is that producers that only occasionally generate their longs will not get their data processed until their *Buffer gets filled up, which may take some time, (you could push off the Buffer before the array gets full, in such a thread.
b) Declare a Buffer struct with an array to hold some longs and an index. Protect with a mutex/futex/CS lock. malloc() just one shared *Buffer and have all the threads get the lock, push on their long and release the lock. If a thread pushes in the last array position, queue the *Buffer to the consumer thread on a producer-consumer queue, immediately malloc a new *Buffer and then release the lock. The consumer gets the *Buffers and processes them and then free()s them, (or queues them off somewhere else, or pushes them back onto a pool for re-use by producers).
You may want to take condition in consideration. Take a look at this piece of code for consumer :
while( load == 0 )
pthread_cond_wait( &notEmpty, &mutex );
What it does is to check to see whether load ( where you store the number of elements in your list ) is zero or not and if it is zero, it'll wait until producer produces new item and put it in the list.
You should implement the same condition for producer ( when it wants to put item in a full list )

Where to use binary semaphore when mutex are available?

While reading about binary semaphore and mutex I found the following difference:
Both can have value 0 and 1, but mutex can be unlocked by the same
thread which has acquired the mutex lock. A thread which acquires
mutex lock can have priority inversion in case a higher priority
process wants to acquire the same mutex whereas this is not the case
with binary semaphore.
So where should I use binary semaphores? Can anyone cite an example?
EDIT: I think I have figured out the working of both. Basically binary semaphore offer synchronization whereas mutex offer locking mechanism. I read some examples from Galvin OS book to make it more clear.
One typical situation where I find binary semaphores very useful is for thread initialization where the thread will read from a structure owned by the parent thread. The parent thread needs to wait for the new thread to read the shared data from the structure before it can let the structure's lifetime end (by leaving its scope, for instance). With a binary semaphore, all you have to do is initialize the semaphore value to zero and have the child post it while the parent waits on it. Without semaphores, you'd need a mutex and condition variable and much uglier program logic for using them.
In almost all cases I use binary semaphore to signal other thread without locking.
Simple example of usage for synchronous request:
Thread 1:
Semaphore sem;
request_to_thread2(&sem); // Function sending request to thread2 in any fashion
sem.wait(); // Waiting request complete
Thread 2:
Semaphore *sem;
process_request(sem); // Process request from thread 1
sem->post(); // Signal thread 1 that request is completed
Note: You before post semaphore in thread 2 processing you can safely set thread 1 data without any additional synchronization.
The canonical example for using a counted semaphore instead of a binary mutex is when you have a limited number of resources available that are a) interchangeable and b) more than one.
For instance, if you want to allow a maximum of 10 readers to access a database at once, you can use a counted semaphore initialized to 10 to limit access to the resource. Each reader must acquire the semaphore before accessing the resource, decrementing the available count. Once the count reaches 0 (i.e. 10 readers have gained access to, and are stil using the database), all other readers are locked out. Once a reader finishes, they bump semaphore count back up by one to indicate that they are no longer using the resource and some other reader may now obtain the semaphore lock and gain access in their stead.
However, the counted semaphore, just like all other synchronization primitives, has many use cases and it's just a matter of thinking outside the box. You may find that many problems you are used to solving with a mutex plus additional logic can be more-easily and more-straightforwardly implemented with a semaphore. A mutex is a subset of the semaphore, that is to say, anything you can do with a mutex can be done with a semaphore (simply set the count to one), but that there are things that can be done with a semaphore alone that cannot be done with just a mutex.
At the end of the day, any one synchronization primitive is generally enough to do anything (think of it as being "turing-complete" for thread synchronization, to bastardize that word). However, each is tailor-fit to a different application, and while you may be able to force one to do your bidding with some customization and additional glue, it is possible that a different synchronization primitive is better-fit for the job.

Resources