0

I have synchronization problem creating the producer/consumer problem with semaphore in python 3.5. In particular when I acquire the producer semaphore, simultaneously (I think this is the problem, but I'm not sure and if so I don't know why) the consumer semaphore acquired, and this means that It's a block of the producer (in the print), since it's unable to enter in the "if the buff is full" statement. This is my code in particular:

import random
from queue import Queue
import threading


class producer (threading.Thread):
    def __init__(self, buff, semaphore):
        threading.Thread.__init__(self)
        self.bf = buff
        self.semaphore = semaphore

    def run(self):
        while True:
            self.semaphore.acquire()
            if self.bf.full():
                self.semaphore.release()
                print("Producer: The buff is full, waiting...")
            else:
                x = random.randint(1,9)
                print("Producer: I produced the object # ", x)
                self.bf.put(x)


class consumer (threading.Thread):
    def __init__(self, buff, semaphore):
        threading.Thread.__init__(self)
        self.bf = buff
        self.semaphore = semaphore

    def run(self):
        while True:
            self.semaphore.acquire()
            if self.bf.empty():
                self.semaphore.release()
                print("Consumer: The buff is empty, waiting...")
            else:
                print("Consumer: I consumed the object # ", self.bf.get())


class main:
    MAX_LEN = 10
    semaphore = threading.BoundedSemaphore(value=MAX_LEN)
    buff = Queue(maxsize=MAX_LEN)
    producer = producer(buff, semaphore)
    producer.start()
    consumer = consumer(buff, semaphore)
    consumer.start()


if __name__ == '__main__':
    main

And the result of this is:

Producer: I produced the object #  9
Producer: I produced the object #  3
Producer: I produced the object #  2
Producer: I produced the object #  1
Producer: I produced the object #  4
Producer: I produced the object #  5
Producer: I produced the object #  2
Producer: I produced the object #  1
Producer: I produced the object #  4
Producer: I produced the object #  1

What I can do for solve this horrible problem?

Alucard994
  • 19
  • 2
  • Could you please elaborate more on why sharing a semaphore between the producer and the consumer? It seems that the semaphore is being acquired on each loop for both `producer` and `consumer`, but it's only released when the buffer can't be used. So when the buffer is actually being used, the semaphore counter keeps decreasing. When the counter hits zero, the call to `acquire()` blocks waiting for another `release()` which won't happen. – farzad Mar 21 '16 at 09:50
  • 2
    I'm not sure a semaphore is needed at all. The `Queue` classes from the `Queue` module already use synchronization primitives internally, so you shouldn't need anything more unless you're doing something complicated. – Blckknght Mar 21 '16 at 09:51
  • mmh, i'm not sure it's right.. If i don't use a synchronization method (lock, semaphore, etc) it's not synchronized correctly, with the result of print many times "The buffer is full/empty" – Alucard994 Mar 21 '16 at 15:04
  • did you solve your problem ? – aysebilgegunduz Apr 13 '16 at 09:41
  • yes, I solve my problem using two nested semaphore... And then, considering that with only semaphores nested it works, but I could not use more producers, I added a further semaphore mutex to ensure mutual exclusion. If you want, I can post my solution. – Alucard994 Apr 14 '16 at 10:40

0 Answers0