作业用C#语言,在Visio Studio 2017 环境下编译完成的。 要求:设计一个test.cpp,定义变量:unsigned int sum=0;创建2个线程T1和T2, T1的行为:sum+=1;T2的行为: sum+=2;当sum大于1000000时,输出sum的值,程序结束。 Q1:将该程序运行10次,记录运行结果。 Q2:10次运行结果是否一致?若不一致,请解释原因。 10次的运行结果并不完全一致,这是由于两个线程几乎同时在使用同一个公共变量导致的。举个例子,线程1在执行完sum+=1后,sum的值刚刚赋为100001,这是线程2恰好开始执行sum+=2,这是对于线程2来说,上一次判断是否继续执行sum+=2时的sum值为99999<100000,所以继续操作,这时由于进程1刚刚给sum赋值为100001,所以线程2再次执行后的结果就是100003。 Q3:设计另一个autorun.cpp,它能够将test.exe运行N次(n=10000或100000…),自动收集运行结果存入result.txt文件。 Q4:是否可以消除test.exe多次运行时其结果的不一致性?请给出解决方案,测试其可行性。 运行结果 要求:设计一个quadratic.cpp,用于求解N个(n=10000或100000…)一元二次方程,方程的系数a、b、c为随机整数,其中a ≠ 0。将quadratic.cpp改造为采用2个线程协同求解一元二次方程的Multithreading2.cpp。 数据部分截图 运行结果 运行结果 Q1:分别计算quadratic.cpp与Multithreading2.cpp的运行时间。 Q2:计算Multithreading2.cpp的加速比。 加速比=T(quadratic)/T(Multithreading2)≈0.96 Q3:分析总结串行算法并行化改造的难点。 改造难点在于对问题的划分第一题
步骤1:创建线程并启动
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; namespace ThreadWork { public class Threads { private int sum = 0; private LockSpace l = new LockSpace(); public void AddOne() { while (sum <= 1000000) { sum += 1; } Console.WriteLine("AddOne:{0}", sum); } public void AddTwo() { while (sum <= 1000000) { sum += 2; } Console.WriteLine("AddTwo:{0}", sum); ; } } public class Program { static void Main(string[] args) { Threads th = new Threads(); ThreadStart t1 = new ThreadStart(th.AddOne); ThreadStart t2 = new ThreadStart(th.AddTwo); Thread T1 = new Thread(t1); Thread T2 = new Thread(t2); T1.Start(); T2.Start(); Console.ReadKey(); } } }
步骤2:自动启动线程
using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Repeat { class Program { static void Main(string[] args) { string msg;//放置exe文件的输出 string path = "result.txt";//文件的路径,保证文件存在。 Console.WriteLine("开始写入。"); for (int i = 0; i < 10000; i++) {//需要循环多少次i就小于多少 Process cmd = new Process();//实例化进程 FileStream fs = new FileStream(path, FileMode.Append);//实例化文件流 StreamWriter sw = new StreamWriter(fs);//实例化写入流 cmd.StartInfo.FileName = "ThreadWork.exe";//给定即将开启的进程名称 cmd.StartInfo.UseShellExecute = false;//精确查找路径来执行,不支持各种非可执行程序的打开 cmd.StartInfo.RedirectStandardInput = true;//重定向输入 cmd.StartInfo.RedirectStandardOutput = true;//重定向输出 cmd.StartInfo.CreateNoWindow = true;//不开启新的窗口 cmd.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;//隐藏窗口样式 Console.WriteLine("第{0}次执行线程。", i + 1); sw.WriteLine("第{0}次执行线程。", i + 1);//追加写入文件 cmd.Start(); msg = cmd.StandardOutput.ReadToEnd();//获取exe文件的输出,但只有在关闭进程后才能真正获取 cmd.WaitForExit();//等待程序退出 cmd.Close();//关闭进程 sw.WriteLine(msg);//追加写入exe文件的输出 Console.WriteLine(msg); sw.Close();//关闭写入流 fs.Close();//关闭文件流 } Console.ReadKey(); } } }
步骤3:回答问题
步骤2已经完成这个问题。下图为部分截图。
多次运行结果不一致的问题是可以解决的,通过加锁就可以解决结果不一致性。 public class LockSpace { } public class Threads { private int sum = 0; private LockSpace l = new LockSpace(); public void AddOne() { lock (this.l) { while (sum <= 1000000) { sum += 1; } Console.WriteLine("AddOne:{0}", sum); sum = 0; } } public void AddTwo() { lock (this.l) { while (sum <= 1000000) { sum += 2; } Console.WriteLine("AddTwo:{0}", sum); sum = 0; } } }
第二题
步骤1:造一元二次方程的系数数据
string path = "Coefficients.txt"; FileStream fs = new FileStream(path, FileMode.Append); StreamWriter sw = new StreamWriter(fs); StreamReader sd = new StreamReader(fs, Encoding.UTF8); Random num = new Random(); Console.WriteLine("随机创建10000条一元二次方程的系数数据。"); Console.WriteLine("开始写入。。。"); for (int i = 0; i < 10000; i++) { sw.Write(num.Next(1, 10) + "t" + num.Next(1, 10) + "t" + num.Next(1, 10)); sw.WriteLine(); } sw.Close(); fs.Close(); Console.WriteLine("写入完成10000条数据完成。");
步骤2:计算一元二次方程的解
using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Quadratic { class Program { //调用winAPI中的QueryPerformanceFrequency()方法,返回硬件支持的高精度计数器的频率 [System.Runtime.InteropServices.DllImport("Kernel32.dll")] static extern bool QueryPerformanceFrequency(ref long count); //调用winAPI中的QueryPerformanceCounter()方法,用于获取精确的性能计数器数值 [System.Runtime.InteropServices.DllImport("Kernel32.dll")] static extern bool QueryPerformanceCounter(ref long count); static void Main(string[] args) { string path = "Coefficients.txt"; StreamReader sr = new StreamReader(path, Encoding.Default); //path为文件路径 String line; int lines = 0; long start = 0; long end = 0; long freq = 0; double result = 0; //频率 QueryPerformanceFrequency(ref freq); Console.WriteLine("开始进行方程求解。。"); //开始计时 QueryPerformanceCounter(ref start); while ((line = sr.ReadLine()) != null)//按行读取 line为每行的数据 { lines++; string s = line.Replace("t", ""); //一元二次方程的形式为:a*x*x+b*x+c=0; int a = Convert.ToInt32(s.Substring(0, 1)); int b = Convert.ToInt32(s.Substring(1, 1)); int c = Convert.ToInt32(s.Substring(2, 1)); double x1 = 0;//实数根1 double x2 = 0;//实数根2 double dt = b * b - 4 * a * c; if (dt == 0) { x1 = -b / 2 * a; Console.WriteLine("方程{0}x*x+{1}*x+{2}=0,有两个相等的实根,x1=x2={3}!", a, b, c, x1.ToString("F")); } else if (dt > 0) { x1 = (-b + Math.Sqrt(dt)) / 2 * a; x2 = (-b - Math.Sqrt(dt)) / 2 * a; Console.WriteLine("方程{0}x*x+{1}*x+{2}=0,有两个不相等的实根,x1={3}、x2={4}", a, b, c, x1.ToString("F"), x2.ToString("F")); } } Console.WriteLine("共计{0}条数据计算完毕。", lines); //结束计时 QueryPerformanceCounter(ref end); //计算时间 result = (double)(end - start) / (double)freq; Console.WriteLine("共计用时:{0}s", result); Console.ReadKey(); } } }
步骤3:用线程改造quadratic项目
思路:线程1计算并保存△>0的系数数据,线程2计算结果并输出。
using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace Quadratic { public class MultiThread { public List<string> realList = new List<string>(); public void DtThread() { StreamReader sr = new StreamReader("Coefficients.txt", Encoding.Default); //path为文件路径 String line; //int lines = 0; while ((line = sr.ReadLine()) != null)//按行读取 line为每行的数据 { //lines++; string s = line.Replace("t", ""); //一元二次方程的形式为:a*x*x+b*x+c=0; int a = Convert.ToInt32(s.Substring(0, 1)); int b = Convert.ToInt32(s.Substring(1, 1)); int c = Convert.ToInt32(s.Substring(2, 1)); double dt = b * b - 4 * a * c; if (dt >= 0) { // lines++; realList.Add(line); } } //Console.WriteLine("reallist:" + realList.Count); } public void CalThread() { double x1 = 0;//实数根1 double x2 = 0;//实数根2 for (int i = 0; i < realList.Count; i++) { string s = realList[i].Replace("t", ""); int a = Convert.ToInt32(s.Substring(0, 1)); int b = Convert.ToInt32(s.Substring(1, 1)); int c = Convert.ToInt32(s.Substring(2, 1)); double dt = b * b - 4 * a * c; if (dt == 0) { x1 = -b / 2 * a; Console.WriteLine("方程{0}x*x+{1}*x+{2}=0,有两个相等的实根,x1=x2={3}!", a, b, c, x1.ToString("F")); } else if (dt > 0) { x1 = (-b + Math.Sqrt(dt)) / 2 * a; x2 = (-b - Math.Sqrt(dt)) / 2 * a; Console.WriteLine("方程{0}x*x+{1}*x+{2}=0,有两个不相等的实根,x1={3}、x2={4}", a, b, c, x1.ToString("F"), x2.ToString("F")); } } } } public class Program { //调用winAPI中的QueryPerformanceFrequency()方法,返回硬件支持的高精度计数器的频率 [System.Runtime.InteropServices.DllImport("Kernel32.dll")] static extern bool QueryPerformanceFrequency(ref long count); //调用winAPI中的QueryPerformanceCounter()方法,用于获取精确的性能计数器数值 [System.Runtime.InteropServices.DllImport("Kernel32.dll")] static extern bool QueryPerformanceCounter(ref long count); static void Main(string[] args) { long start = 0; long end = 0; long freq = 0; double result = 0; MultiThread mt = new MultiThread(); ThreadStart dt = new ThreadStart(mt.DtThread); ThreadStart cal = new ThreadStart(mt.CalThread); Thread t1 = new Thread(dt); Thread t2 = new Thread(cal); //频率 QueryPerformanceFrequency(ref freq); Console.WriteLine("开始进行方程求解。。"); //开始计时 QueryPerformanceCounter(ref start); t1.Start(); t1.Join(); t2.Start(); t2.Join(); //结束计时 QueryPerformanceCounter(ref end); //计算时间 result = (double)(end - start) / (double)freq; Console.WriteLine("共计用时:{0}s", result); Console.ReadKey(); } } }
步骤4:回答问题
本网页所有视频内容由 imoviebox边看边下-网页视频下载, iurlBox网页地址收藏管理器 下载并得到。
ImovieBox网页视频下载器 下载地址: ImovieBox网页视频下载器-最新版本下载
本文章由: imapbox邮箱云存储,邮箱网盘,ImageBox 图片批量下载器,网页图片批量下载专家,网页图片批量下载器,获取到文章图片,imoviebox网页视频批量下载器,下载视频内容,为您提供.
阅读和此文章类似的: 全球云计算