简体   繁体   中英

MultiThreading with Python

This is a Producer Consumer Problem. I need a single producer and multiple consumers to access the shared data cell and each consumer needs to access the produced data before the producer makes additional data. The code works fine when there is a single consumer. I have attempted to make a list of the Producer and Consumers in order to.join() and.start() them. The program works so far as the first consumer, but hangs up when it gets to the second consumer. I have tried to change the locking mechanisms from "notify" to "notifyAll" in the getData and setData, I am a beginner in python and this stuff is pretty foreign to me but I have been trying stuff for 10 hours and would really appreciate some help.

import time, random
from threading import Thread, currentThread, Condition

class SharedCell(object):
    
    def __init__(self):
        self.data = -1
        self.writeable = True
        self.condition = Condition()
        
    def setData(self, data):
        self.condition.acquire()
        while not self.writeable:
            self.condition.wait()
        
        print("%s setting data to %d" % \
              (currentThread().getName(), data))
        self.data = data
        self.writeable = False
        self.condition.notifyAll()
        self.condition.release()
    
    def getData(self):
        self.condition.acquire()
        while self.writeable:
            self.condition.wait()
        print(f'accessing data {currentThread().getName()} {self.data}')
        self.writeable = True
        self.condition.notifyAll()
        self.condition.release()
        return self.data
    
class Producer(Thread):
    
    def __init__(self, cell, accessCount, sleepMax):
        Thread.__init__(self, name = "Producer")
        self.accessCount = accessCount
        self.cell = cell
        self.sleepMax = sleepMax
    
    def run(self):
        
        print("%s starting up" % self.getName())
        for count in range(self.accessCount):
            time.sleep(random.randint(1, self.sleepMax))
            self.cell.setData(count + 1)
        print("%s is done producing\n" % self.getName())
        
class Consumer(Thread):
    
    def __init__(self, cell, accessCount, sleepMax):
        Thread.__init__(self)
        self.accessCount = accessCount
        self.cell = cell
        self.sleepMax = sleepMax
        
    def run(self):

        print("%s starting up" % self.getName())
        for count in range(self.accessCount):
            time.sleep(random.randint(1, self.sleepMax))
            value = self.cell.getData()
        print("%s is done consuming\n" % self.getName())
        
def main():
    accessCount = int(input("Enter the number of accesses: "))
    sleepMax = 4
    cell = SharedCell()
    
    producer = Producer(cell, accessCount, sleepMax)
    consumer = Consumer(cell, accessCount, sleepMax)
    consumerTwo = Consumer(cell, accessCount, sleepMax)
    
    threads = []
    threads.append(producer)
    threads.append(consumer)
    threads.append(consumerTwo)
    
        
    print("Starting the threads")      
   
    for thread in threads:
        thread.start()
        thread.join()

main()

The join function blocks the current thread and waits until the indicated thread terminates. In your loop at the end of your main function, why do you join each thread immediately after starting it? That would result in starting thread 1, and then waiting for it to terminate before starting thread 2, and then waiting that it to terminate before starting thread 3, and so on.

Perhaps you meant something like this:

for thread in threads:
    thread.start()

for thread in threads:
    thread.join()

so that every thread is started before you wait for them to terminate.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM