2
votes

So I've got this code for Producers and Consumers;

import threading

import time

import random

N = 8


buffer = N * [None]

free = threading.Semaphore(N)

items = threading.Semaphore(0)

def prod():

    n = 0
    i = 0
    while True:
        time.sleep(random.random())
        free.acquire()
        buffer[i] = n
        i = (i + 1) % N
        n += 1
        items.release()

def cons():

    i = 0
    while True:
        time.sleep(random.random())
        items.acquire()
        print(buffer[i])
        i = (i + 1) % N
        free.release()

def main():

    p = threading.Thread(target=prod, args=[])
    c = threading.Thread(target=cons, args=[])
    p.start()
    c.start()
    p.join()
    c.join()

main()

But I want to be able to have three threads each for the producer and consumer. Can someone suggest a way I could do this using a third semaphore? Thanks.

1

1 Answers

1
votes

Assuming this is not a homework about semaphores and you want a real solution, you should use the Queue object, which can handle all of this by itself. If I understood it correctly, you want three producers and three consumers that share one buffer that can have at maximum 8 items. If that's the case, the code can be simplified to something like this:

import threading
import Queue

def prod(queue):
    n = 0
    while True:
        time.sleep(random.random())
        queue.put(n)
        n += 1

def cons(queue):
    while True:
        time.sleep(random.random())
        n = queue.get()
        print n

def main():
    N = 8
    queue = Queue.Queue(N)
    threads = []
    for i in range(3):
        threads.append(threading.Thread(target=cons, args=[queue])))
        threads.append(threading.Thread(target=prod, args=[queue])))
    for thread in threads:
        thread.start()
    for thread in threads:
        thread.join() # this will never really finish, because the threads run forever

If you are interested how is the queue implemented internally, you can see the source code here.