/// <summary> /// Consumer thread that pulls values from the numbers queue and determines if they are prime /// </summary> /// <param name="state">Contains the id of the thread</param> static void ConsumerThread(object state) { int id = (int)state; UpdateThreadStatus(id, false, '+'); List <ulong> primes = m_Primes[id]; while (m_ProducersComplete.WaitOne(1) == false || m_Numbers.Count > 0) { ulong number; if (m_Numbers.TryDequeue(out number)) { UpdateThreadStatus(id, false, 'X'); if (MathStuff.IsPrime(number)) { primes.Add(number); } UpdateThreadStatus(id, false, '+'); } // end of if } // end of while UpdateThreadStatus(id, false, '-'); } // end of method
/// <summary> /// Main program /// </summary> /// <param name="args"></param> static void Main(string[] args) { Console.BufferHeight = 9999; ulong highest = IOFunctions.GetULongFromUser("Enter largest number to test for prime: ", 2, 100000000UL); int producerThreadCount = IOFunctions.GetIntFromUser("Enter number of producer threads (1 - 64): ", 1, 64); int consumerThreadCount = IOFunctions.GetIntFromUser("Enter number of consumer threads (1 - 64): ", 1, 64); OutputHeader(); ulong approxNumPrimes = MathStuff.ApproximateNumberOfPrimes(highest); List <Thread> producerThreads = new List <Thread>(); List <Thread> consumerThreads = new List <Thread>(); DateTime startTime = DateTime.Now; // Create the producer threads for (int i = 0; i < producerThreadCount; i++) { Thread producer = new Thread(ProducerThread); producer.Start(new Tuple <int, int, ulong>(i, producerThreadCount, highest)); producerThreads.Add(producer); } // Create the consumer threads for (int i = 0; i < consumerThreadCount; i++) { Thread consumer = new Thread(ConsumerThread); // Create the List of ulongs that the consumer will place its results into // Also, use the approx. # of primes to minimize list resizing List <ulong> primes = new List <ulong>((int)(approxNumPrimes / (uint)consumerThreadCount)); // Add that list to m_Primes, using the thread's ID as its key m_Primes.Add(i, primes); consumer.Start((int)i); consumerThreads.Add(consumer); } // Create the timer that will output the number of numbers left to process m_Timer = new Timer(CountTimerCallback, null, 500, 500); // Wait for producer threads... foreach (Thread thread in producerThreads) { thread.Join(); } // Signal to all consumers that no more values will be produced m_ProducersComplete.Set(); // Wait for consumer threads... foreach (Thread thread in consumerThreads) { thread.Join(); } m_Timer.Dispose(); DateTime endTime = DateTime.Now; CountTimerCallback(null); Console.SetCursorPosition(0, 8); Console.WriteLine("Processing took: {0} ms", endTime.Subtract(startTime).TotalMilliseconds); ShowStats(); ShowPrimes(highest); Console.WriteLine(); Console.Write("Press <ENTER> to quit..."); Console.ReadLine(); }