0

I am trying to show that the following solution of the producer/consumer problem does not work, by showing that when a consumer is at the beginning of M1, there is a case when it won't be able to dequeue an item within a finite time, and/or there is a case when a producer is at the beginning of L2, and it will not be able to enqueue an item within a finite time. I just can't find any example to prove it.

The algorithm assumes there are 10 producers, 10 consumers, and a buffer size of 10.

nf = 0; // counting semaphore, # of items in queue
bm = 1; // binary semaphore, ensures mutex

Producer

L1: Produce(item);
L2: P(bm);
If (queue_is_full) {
  V(bm);
  GoTo L2;
} else {
  Enqueue(item);
  V(bm);
  V(nf);
  GoTo L1;
}

Consumer

M1: P(nf);
P(bm);
Dequeue(item);
V(bm);
Consume(item);
GoTo M1;
ratsimihah
  • 1,010
  • 1
  • 11
  • 22
  • is this by any chance related to live locks? http://docs.oracle.com/javase/tutorial/essential/concurrency/starvelive.html – Osama Javed Apr 16 '13 at 18:25
  • Yes. I think all concurrency problems are. But semaphores are supposed to prevent them from happening. – ratsimihah Apr 16 '13 at 18:27
  • concurrency bugs are usually more to do with deadlocks.. livelocks are generally hypothetical in nature unless the semaphores are designed to give preference to a certain class of customers. E.g in the code above there is nothing preventing the code from continuously looping in the producer, always acquiring the lock before someone else gets a chance to acquire the lock. (although in real life due to non deterministic nature of concurrent systems, you would expect others to acquire the lock, although there is no guarantee as to the finite amount of time required to achieve this – Osama Javed Apr 16 '13 at 18:30
  • I can elaborate with an example if you want – Osama Javed Apr 16 '13 at 18:34
  • Are you referring to the livelock where a producer takes a lock, checks if the queue is full, releases the lock, then takes it, and a consumer checks the lock at the wrong time, and so on? If not, I would appreciate an example. Thank you. – ratsimihah Apr 16 '13 at 20:20
  • yeah . pretty much. There does not seem to be a deadlock. – Osama Javed Apr 17 '13 at 12:38
  • What if the semaphore is strongly fair (e.g: a process can't get stuck at P(s) if another one is doing an infinite number of V(s))? – ratsimihah Apr 17 '13 at 16:15
  • In that case I do not see any problems. Maybe code this up and see if a system locks? – Osama Javed Apr 17 '13 at 16:48
  • Are you sure there is no way the consumer can get stuck at M1 or the consumer stuck in the if loop? – ratsimihah Apr 17 '13 at 20:58

1 Answers1

0

if my understanding is correct P(x) is locking till x != 0 and v(x) always does x++.

In the code above M1: P(nf); will only let the consumer through if an item is available on the queue.It then always acquires and releases the lock on bm . So I am pretty sure the code cannot get deadlocked with other consumers or producers.

In the producer it acquires bm and then operates on the list. It does not acquire any other lock before v(bm) and it performs v(bm) in both branches so it is guaranteed to happen. Since v(bm) will eventually happen a consumer can eventually consume an item. After v(bm) a v(nf) is guaranteed therefore when an item is produced one consumer will attempt to eventually consume it.

Therefore the code looks fine unless there is something silly like listcapacity == 0.

there would be issues if consumer did P(bm)-> P(nf)-> V(bm) but the code above looks fine

Osama Javed
  • 1,432
  • 1
  • 16
  • 21
  • Thanks for the extensive explanation. It makes sense and I came up with the same conclusion. I should learn more about it today and will let you know then. – ratsimihah Apr 18 '13 at 13:09
  • The code actually doesn't work. A producer can keep filling the queue and a consumer emptying it, while another producer checks if the queue is full at the wrong time and loops forever. – ratsimihah Apr 20 '13 at 19:12
  • @bluepanda again that would be a live lock. So lets say there is a producerA and a producerB . So A produces and stores an item. The queue is now full. Producer B tries to deposit its item but it cant since queue is full. Consumer C comes and consumes the item. Now either A or B or any other producer in the system can deposit their stuff and which producer can do p(bm) **should** be non deterministic. The answer above says there are no deadlocks in the code since I mentioned live locks in the original comments. If there is a deadlock I would really like to see a trace of execution. – Osama Javed Apr 21 '13 at 00:10