This can then be derived like this: public class BusyWaitingProducerConsumer : ProducerConsumerBase _TotalNumberOfValues = totalNumberOfValues Protected ProducerConsumerBase(int bufferSize, int totalNumberOfValues) Something along these lines: public class ProducerConsumerBase You should also pass the buffer size and values to produce/consume as parameters to break dependencies on global variables. The easiest way to simplify this is to provide an abstract base class which the various implementations can derive from an implement. It is all static methods and global variables which seriously hurts maintenance and makes testing the code real painful as you probably have already discovered (I guess you have managed with a lot of commenting in and out code). Following standard naming conventions makes your code look more familiar to other C# developers. For static and instance members there are more variants around but often they are prefixed with _ and/or area also PascalCase so they can be easily distinguished from local variables and parameters. Standard C# naming convention for methods is PascalCase. This is the busy-waiting producer/consumer and their related global variable: static int avail = 0 īuffer = (char)(32 + i % 95) Ĭonsole.WriteLine("Produced: ", buffer) Thread c = new Thread(new ThreadStart(nsume)) Thread p = new Thread(new ThreadStart(Program.produce)) This is the part of the code that never changes: const int buffSize = 10 ![]() The Monitor variation looks as if there should be a simpler solution with fewer variables. All of these reside in a class named Program, which is needed for the threading. I implemented three variations, a busy-waiting variation, a Semaphore variation, and a Monitor variation. I have never written a multi-threaded program before, nor have I written a program with mutual exclusion before, so I decided to request a review here. ![]() The class does not involve writing code, but I decided to implement a bounded buffer version of this problem. Moi python $ python boundedbuffer_semaphore.I am studying mutual exclusion in college, and we just covered the producer/consumer problem. Print("'".format(buf, buf, consumer_idx)) Producer_idx = (producer_idx + 1) % buf_size Global producer_idx, counter, buf, buf_size Raise ValueError('Result size is %d instead of %d' % (len(result), value_count)) Here's a small test program I used to play around: def producer(queue, start, end, step):ĭef consumer(queue, count, result, lock): Self.read_index = (self.read_index + 1) % len(self.buff) Self.write_index = (self.write_index + 1) % len(self.buff) Also, I think you could access the buffer without holding the locks (because lists themselves are thread-safe): def put(self, val): I would remove the size attribute in favor of len(self.buff) though and rename the start and end indices to read_index and write_index respectively (and the locks as well). ( CPython's queue implementation does this.) You could remove one of the locks and use it in both get and put to protect both the start and the end index which wouldn't allow consumers and producers to access the queue simultaneously. The two semaphores are definitely necessary. The semaphores prevent concurrent producers and consumers from writing and reading too much and the locks prevent concurrent producers or consumers from modifying the end or start indices simultaneously. Is this implementation bug-free? Could this be simplified further to use fewer mutexes/semaphores? Self.closed = Semaphore(size) # block till there's item to consumeįor _ in range(size): # initialize with all closed acquired so that consumer is blocked Self.open = Semaphore(size) # block till there's space to produce Self.start_lock = Lock() # protect start from race across multiple consumers Self.end_lock = Lock() # protect end from race across multiple producers ![]() I'm trying to understand how to implement a Queue with a bounded buffer size that can be used by multiple producers and consumers using Python Semaphores.
0 Comments
Leave a Reply. |
AuthorWrite something about yourself. No need to be fancy, just an overview. ArchivesCategories |