我在Mac 2上运行类似的代码示例,一个在C中,另一个在C#中. 2个并行执行的简单任务(或者至少我希望它们),一个循环打印,另一个打印循环.我期待2个样本的输出非常相似,但是我觉得它们有点不同.
C似乎真正并行运行任务.我可以看到 – 在每次运行中都很好地交替,但C#似乎运行一个任务一段时间,然后切换到另一个任务并运行一段时间.像这样的东西:
C++: +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ C# : ++++++++++---------++++++------
我理解无法对并行线程的运行方式做出假设,我很好奇C一致地产生了如此好的结果.
谢谢你的时间!
C#:
using System; using System.Threading.Tasks; public class ConcurrentTasks { public static void Main(String[] args) { var task1 = Task.Run(()=>DemoTask("+")); var task2 = Task.Run(()=>DemoTask("-")); var res1 = task1.Result; var res2 = task2.Result; Console.WriteLine("\nResults:"); Console.WriteLine(res1); Console.WriteLine(res2); } private static String DemoTask(String label) { for (int i = 0; i < 1000; i++) { Console.Write(label); } return label + " result"; } } // mcs ConcurrentTasks.cs // mono ConcurrentTasks.exe
C :
#include <iostream> #include <sstream> #include <future> using namespace std; string demoTask(char label) { for (int i = 0; i < 1000; i++) { cout << label; } stringstream ss; ss << label; ss << " result"; return ss.str(); } int main() { auto task1 = async(demoTask,'+'); auto task2 = async(demoTask,'-'); auto res1 = task1.get(); auto res2 = task2.get(); cout << endl << "Results:" << endl; cout << res1 << endl; cout << res2 << endl; return 0; } // g++ --std=c++14 -Wall ConcurrentTasks.cpp -o ConcurrentTasks.exe // ./ConcurrentTasks.exe
编辑:我已经将C#示例更改为使用裸线程,结果是相同的.
C#with Thread:
using System; using System.Threading; public class ConcurrentTasks { public static void Main(String[] args) { var t1 = new Thread(() => DemoTask("+")); var t2 = new Thread(() => DemoTask("-")); t1.Start(); t2.Start(); } private static String DemoTask(String label) { for (int i = 0; i < 1000; i++) { Console.Write(label); } return label + " result"; } }
解决方法
粒度可能是一个原因. TPL可能具有调度任务的粗粒度,但C异步实现可能具有精细的粒度.这实际上意味着C将花费更多的时间,因为只是为了处理或 – 它正在调度其中的另一个任务.
另一个原因可能是cout和Console如何实现输出流.如何在屏幕上呈现某些东西?是否正在实施缓冲?你看,Console.Write可能正在缓冲,然后一段时间后打印,但cout可能只是立即打印它.
因此,你应该做一些其他的事情,而不是依赖于语言的底层I / O–可以将字符放在共享的静态大小的数组上,使用共享的int作为共享数组的索引(它们是原子的,不需要锁用最轻的同步原语(如读写器锁)锁定它.不,不要使用矢量或数组 – 因为在这种情况下,你再次依赖于你不知道的东西!
在两种情况下都使用Release版本,并使用尽可能相同的优化选项.此外,请确保您在同一台计算机上运行它们.