【发布时间】:2019-12-12 03:52:12
【问题描述】:
我有一个任务,我的任务是用 c# 编写一个程序来测试 5 个不同的功能。我似乎遇到了问题,因为这些测试的时间输出似乎是错误的(即它们总是返回 0ms)。此外,我的未同步线程总是返回 5000 的完整值,而他们不应该一直这样做,我在测试#2 中做错了什么,我是否在错误的区域停止了计时器?在这一点上,线程有点让我心烦意乱,我想对此事进行一些澄清......下面是规范和我的代码......
测试#1:将是值 5000 的增量(基本)。
测试#2:主线程将创建 10 个线程,每个线程将共享整数递增 500 次。您不会使用任何同步来保护共享整数的更新。对共享整数的非同步访问很可能会导致它的最终值不正确(
测试#3:主线程将创建 10 个线程,每个线程将共享整数递增 500 次。您将使用互斥锁保护共享整数的更新。
测试#4:主线程将创建 10 个线程,每个线程将共享整数递增 500 次。您将使用 Interlocked 类的 Increment 方法更新共享整数。
测试#5:主线程将创建 10 个线程,每个线程将共享整数递增 500 次。您将使用信号量保护共享整数的更新。
每个测试都将使用 Stopwatch 类进行计时,并且测试所用的总时间将被写入控制台。
使用 Thread.Sleep() 模拟随机数量的处理时间,并假设当时正在使用共享整数。
-
随机时间应该是 0 到 10ms 之间的随机值。
using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Threading; namespace Lab3 { class MainClass { public static int sharedVal = 0; public static int y = 1; static Stopwatch timer = new Stopwatch(); private static Mutex mutex = new Mutex(); private static Semaphore semaphore = new Semaphore(1, 1); public static void Main(string[] args) { Console.WriteLine("***************** Lab 3 Thread/Synchronization Testing *****************" + "\n"); Console.WriteLine("Starting Test 1 (no Threads)..."); test1(); Console.WriteLine("***************** Lab 3 Thread/Synchronization Testing *****************" + "\n"); Console.WriteLine("Starting Test 2 (Threads without any synchronization)..."); test2(10); Console.WriteLine("***************** Lab 3 Thread/Synchronization Testing *****************" + "\n"); Console.WriteLine("Starting Test 3 (Threads with a mutex)..."); test3(10); Console.WriteLine("***************** Lab 3 Thread/Synchronization Testing *****************" + "\n"); Console.WriteLine("Starting Test 4 (Interlocked Methods)..."); test4(10); Console.WriteLine("***************** Lab 3 Thread/Synchronization Testing *****************" + "\n"); Console.WriteLine("Starting Test 5 (Threads with a semaphore)..."); test5(10); } /*****************************************************************************/ public static void test1() { timer.Reset(); timer.Start(); intChanger(ref sharedVal, 5000,0); Console.WriteLine("Test Complete"); timer.Stop(); Console.WriteLine("Shared Value: {0}, Total time: {1}ms ", sharedVal, timer.ElapsedMilliseconds); clearSharedVal(ref sharedVal); } /*****************************************************************************/ public static void test2(int numOfThreads) { timer.Reset(); timer.Start(); threadCreate(numOfThreads); Console.WriteLine("Test Complete"); Console.WriteLine("Shared Value: {0}, Total time: {1}ms ", sharedVal, timer.ElapsedMilliseconds); clearSharedVal(ref sharedVal); y++; } /*****************************************************************************/ public static void test3(int numOfThreads) { timer.Reset(); timer.Start(); threadCreate(numOfThreads); Console.WriteLine("Test Complete"); Console.WriteLine("Shared Value: {0}, Total time: {1}ms ", sharedVal, timer.ElapsedMilliseconds); clearSharedVal(ref sharedVal); y++; } /*****************************************************************************/ public static void test4(int numOfThreads) { timer.Reset(); timer.Start(); threadCreate(numOfThreads); Console.WriteLine("Test Complete"); Console.WriteLine("Shared Value: {0}, Total time: {1}ms ", sharedVal, timer.ElapsedMilliseconds); clearSharedVal(ref sharedVal); y++; } /*****************************************************************************/ public static void test5(int numOfThreads) { timer.Reset(); timer.Start(); threadCreate(numOfThreads); Console.WriteLine("Test Complete"); Console.WriteLine("Shared Value: {0}, Total time: {1}ms ",sharedVal, timer.ElapsedMilliseconds); clearSharedVal(ref sharedVal); } /*****************************************************************************/ public static void threadCreate(int n) { Thread[] threadArr = new Thread[n]; for (int i = 0; i < n; i++) { threadArr[i] = new Thread(new ThreadStart(WorkThreadFunction)); threadArr[i].Start(); } //join for loop for (int i = 0; i < n; i++) { threadArr[i].Join(); } Console.WriteLine("All Threads have been joined"); timer.Stop(); } /******************************************************************************/ public static void WorkThreadFunction() { switch (y) { case 1: intChanger(ref sharedVal, 500, 1); break; case 2: intChanger(ref sharedVal, 500, 2); break; case 3: intChanger(ref sharedVal, 500, 3); break; case 4: intChanger(ref sharedVal, 500, 4); break; } } /*****************************************************************************/ public static void intChanger(ref int s, int n , int flag) { /******************************************************************************* * Flag Explanation * ******************************************************************************** * int flag = 0 --> unsynchronized single thread adding to shared value * * int flag = 1 --> unsynchronized threads adding to shared value * * int flag = 2 --> synchronized using a mutex * * int flag = 3 --> synchronized using Increment method of Interlocked class * * int flag = 4 --> synchronized using semaphore * ********************************************************************************/ Random rand = new Random(); switch (flag) { case 0: for (int i = 0; i < n; i++) { s++; } break; case 1: for (int i = 0; i < n; i++) { s++; } timer.Stop(); break; case 2: for (int i = 0; i < n; i++) { mutex.WaitOne(); Thread.Sleep(rand.Next(0, 10)); s++; mutex.ReleaseMutex(); } break; case 3: for (int i = 0; i < n; i++) { //Thread.Sleep(rand.Next(0, 10) * 1000); Interlocked.Increment(ref s); } timer.Stop(); break; case 4: for (int i = 0; i < n; i++) { semaphore.WaitOne(); Thread.Sleep(rand.Next(0, 10)); s++; semaphore.Release(); } break; } } /*****************************************************************************/ public static void clearSharedVal(ref int n) { n = 0; } }}
【问题讨论】:
-
对于 2:线程将完成其循环,在您再次调用 thread[i].Start() 之前,将您的 n 增加到 1_000_000,它将以小于 10m 的东西结束。
-
请注意,您也在测量线程启动时间和睡眠时间。我不确定你的目标是什么,但如果你想测量锁定时间,那么你应该记住这一点。线程启动时间最长30ms,你的循环大概是0.0001ms
-
嗯,我想测量整个测试从开始到停止的时间长度。
标签: c# multithreading parallel-processing mutex semaphore