コード例 #1
0
ファイル: Semaphore.cs プロジェクト: Baptista/PC
	private static bool TestSemaphoreInAProducerConsumerContext() {

		const int MIN_TIMEOUT = 0;
		const int MAX_TIMEOUT = 2;
		const int RUN_TIME = 30000;
		const int PRODUCER_THREADS = 1;
		const int CONSUMER_THREADS = 1;
		const int THREADS = PRODUCER_THREADS + CONSUMER_THREADS;
 
		Thread[] tthrs = new Thread[THREADS];
		int[] privateCounters = new int[THREADS];
		Semaphore__ freeSem = new Semaphore__(1);
		Semaphore__ dataSem = new Semaphore__(0);
		bool running = true;
		
		// Create and start consumer threads.
		
		for (int i = 0; i < CONSUMER_THREADS; i++) {
			int tid = i;
			tthrs[i] = new Thread(() => {
				Random rnd = new Random(tid);
				do {
					try {
						dataSem.Acquire();
					} catch (ThreadInterruptedException) {
						break;
					}
					//Thread.Yield();
					freeSem.Release();
					if ((++privateCounters[tid] % 100) == 0) {
						Console.Write("[#c{0}]", tid);
					} else {
						try {
							Thread.Sleep(rnd.Next(MIN_TIMEOUT, MAX_TIMEOUT));
						} catch (ThreadInterruptedException) {
							break;
						}
					}
				} while (Volatile.Read(ref running));					
			});
			tthrs[i].Priority = ThreadPriority.Highest;
			tthrs[i].Start();
		}
		// Create and start producer threads.
		for (int i = CONSUMER_THREADS; i < THREADS; i++) {
			int tid = i;
			tthrs[i] = new Thread(() => {
				Random rnd = new Random(tid);
				do {
					try {
						freeSem.Acquire();
					} catch (ThreadInterruptedException) {
						break;
					}
					// Thread.Yield();
					dataSem.Release();
					if ((++privateCounters[tid] % 100) == 0) {
						Console.Write("[#p{0}]", tid - CONSUMER_THREADS);
					} else {
						try {
							Thread.Sleep(rnd.Next(MIN_TIMEOUT, MAX_TIMEOUT));
						} catch (ThreadInterruptedException) {
							break;
						}
					}
				} while (Volatile.Read(ref running));					
			});
			tthrs[i].Start();
		}
		
		// run the test for a while
		Thread.Sleep(RUN_TIME);
		//Console.ReadLine();
		Volatile.Write(ref running, false);
		Thread.Sleep(50);
		
		// Wait until all threads have been terminated.
		for (int i = 0; i < THREADS; i++) {
			if (tthrs[i].IsAlive) {
				tthrs[i].Interrupt();
			}
			tthrs[i].Join();
		}
		
		// Compute results
		
		Console.WriteLine("\nConsumer counters:");
		int consumptions = 0;
		for (int i = 0; i < CONSUMER_THREADS; i++) {
			consumptions += privateCounters[i];
			if (i != 0 && (i % 5) == 0)
				Console.WriteLine();
			else
				Console.Write(' ');
			Console.Write("[#c{0}: {1,4}]", i, privateCounters[i]);
		}
		if (dataSem.Acquire(0)) {
			consumptions++;
		}
		
		Console.WriteLine("\nProducer counters:");
		int productions = 0;
		for (int i = CONSUMER_THREADS; i < THREADS; i++) {
			productions += privateCounters[i];
			if (i != CONSUMER_THREADS && ((i - CONSUMER_THREADS) % 5) == 0) {
				Console.WriteLine();
			} else {
				Console.Write(' ');
			}
			Console.Write("[#p{0}: {1,4}]", i - CONSUMER_THREADS, privateCounters[i]);
		}
		Console.WriteLine("\nproductions: {0}, consumptios: {1}", productions, consumptions);
		return consumptions == productions;
	}
コード例 #2
0
ファイル: Semaphore.cs プロジェクト: Baptista/PC
	private static bool TestSemaphoreAsLock() {

		const int MIN_TIMEOUT = 0;
		const int MAX_TIMEOUT = 10;
		const int RUN_TIME = 10000;
		const int THREADS = 2;

		Thread[] tthrs = new Thread[THREADS];
		int[] privateCounters = new int[THREADS];
		int[] timeouts = new int[THREADS];
		int sharedCounter = 0;
		Semaphore__ lockSem = new Semaphore__(1);
		
		for (int i = 0; i < THREADS; i++) {
			int tid = i;
			tthrs[i] = new Thread(() => {
				Random rnd = new Random(tid);
				int endTime = Environment.TickCount + RUN_TIME;
				do {
					do {
						try {
							if (lockSem.Acquire(Timeout.Infinite /*rnd.Next(MAX_TIMEOUT)*/)) {
								break;
							}
							//Console.Write('+');
							timeouts[tid]++;
						} catch (ThreadInterruptedException) {}
					} while (true);
					sharedCounter++;
					Thread.Yield();
					lockSem.Release();
					if ((++privateCounters[tid] % 100) == 0) {
						Console.Write("[#{0}]", tid);
					} else {
						Thread.Sleep(rnd.Next(MIN_TIMEOUT, MAX_TIMEOUT));
					}
				} while (Environment.TickCount < endTime);					
			});
			tthrs[i].Start();
		}
		
		// Wait until all threads have been terminated.
		for (int i = 0; i < THREADS; i++)
			tthrs[i].Join();
		
		// Compute results
		
		Console.WriteLine("\nPrivate counters:\n");
		int sum = 0;
		for (int i = 0; i < THREADS; i++) {
			sum += privateCounters[i];
			if ((i % 5) == 0)
				Console.WriteLine();
			else
				Console.Write(' ');
			Console.Write("[#{0}: {1,4}/{2}]", i, privateCounters[i], timeouts[i]);
		}
		return sum == sharedCounter;
	}