C# 是否有任何方法可以知道线程是否释放了CPU?

C# 是否有任何方法可以知道线程是否释放了CPU?,c#,multithreading,C#,Multithreading,我偶然发现了一种奇怪的行为,对此我没有任何理由。在下面的程序中有两个部分。第一部分是注释,它创建了两个线程并做了一些工作,在第二部分中我添加了一些获取素数的代码,我尝试了这些代码来检查AsParallel的性能。阿斯帕莱尔确实缩短了节目时间。但最让我印象深刻的是,当我评论上述部分时,我及时得到了改进。 所以我的问题是,我已经评论过的第一部分是否让CPU足够忙。还是有其他原因 请查看所用时间 1) 第一节未注释时:经过时间:4260619(滴答声) 2) 注释第一节时:经过:2700445(滴答声

我偶然发现了一种奇怪的行为,对此我没有任何理由。在下面的程序中有两个部分。第一部分是注释,它创建了两个线程并做了一些工作,在第二部分中我添加了一些获取素数的代码,我尝试了这些代码来检查AsParallel的性能。阿斯帕莱尔确实缩短了节目时间。但最让我印象深刻的是,当我评论上述部分时,我及时得到了改进。 所以我的问题是,我已经评论过的第一部分是否让CPU足够忙。还是有其他原因

请查看所用时间 1) 第一节未注释时:经过时间:4260619(滴答声) 2) 注释第一节时:经过:2700445(滴答声)

类程序
{
[线程静态]
静态int-thStaticInt=0;
静态void Main(字符串[]参数)
{
//新线程(()=>
//{
//对于(int i=0;i<10;i++)
//    {
//thStaticInt++;
//WriteLine(“从第一个{0}”,thStaticInt);
//    }
//}
//).Start();
//新线程(()=>
//{
//对于(int i=0;i<10;i++)
//    {
//thStaticInt++;
//WriteLine(“从第二个{0}”,thStaticInt);
//    }
//}
//).Start();
//Console.WriteLine(“按任意键”);
//Console.ReadLine();
//另一部分从这里开始
IEnumerable numbers=可枚举范围(31000);
秒表=新秒表();
watch.Start();
var primes=从n开始,以数字表示。AsParallel()
其中可枚举的.Range(2,(int)Math.Sqrt(n)).All(i=>n%i!=0)
选择n;
IEnumerable primeNumbers=primes.ToArray();
看,停;
TimeSpan ts=观察时间已过;
WriteLine(“经过的时间{0}”,ts.Ticks);
Console.ReadLine();
}
}

你没有抓住整个画面。你的分析会导致误解

当您启动一个线程时,您请求操作系统启动一个线程,这并不意味着它立即启动,它只是一个请求。操作系统决定何时运行线程以及运行多长时间。也就是说,在您的示例中,注释部分中的线程可以在第二部分之前、期间甚至之后运行

线程中的工作也有点可疑。10的计数器非常简单。还请记住,从线程写入控制台的操作只有在console类为您执行线程同步时才可能进行。那么,这与时间安排有什么关系呢?我不知道

然后,可能还有其他进程正在运行其他线程,而您不知道

最重要的是,你可能有一个多核处理器,它可能会也可能不会影响一切


分析不是一项容易的任务。你至少应该多次重复你的测试,记录测试结果,并对所涉及的每一件事都有一个坚实的理解。

你并没有掌握完整的情况。你的分析会导致误解

当您启动一个线程时,您请求操作系统启动一个线程,这并不意味着它立即启动,它只是一个请求。操作系统决定何时运行线程以及运行多长时间。也就是说,在您的示例中,注释部分中的线程可以在第二部分之前、期间甚至之后运行

线程中的工作也有点可疑。10的计数器非常简单。还请记住,从线程写入控制台的操作只有在console类为您执行线程同步时才可能进行。那么,这与时间安排有什么关系呢?我不知道

然后,可能还有其他进程正在运行其他线程,而您不知道

最重要的是,你可能有一个多核处理器,它可能会也可能不会影响一切


分析不是一项容易的任务。你至少应该多次重复你的测试,记录测试结果,并对所涉及的每件事都有一个坚实的理解。

我不知道这两个部分是如何相互关联的。这个问题没有很好地表达出来。是的,各部分之间没有关联,我只是在这里和那里添加了一些关于线程和检查代码如何工作的代码,但事实是,当上述两个线程完成任务时,它们如何影响所用的时间。哦,我明白了,你是说如果包括这些线程,那么就需要额外的时间。我会假设,因为线程不是自由的。从池中分配线程、分配worker函数,然后启动线程需要时间——此时操作系统接管并将线程分配给CPU。有各种各样的后台活动正在进行,例如等待时间片和潜在的上下文切换正在进行。这些细节是从你对线程世界的看法中抽象出来的。是的,亚当,谢谢你的及时回复。您已经了解了我的问题,但我仍然不明白,当我看到第一部分的两个线程在控制台上完成打印任务时。我不应该假设既然任务结束了,他们就会释放CPU。不确定。这可能是因为这些线程还没有被GC’d或返回到池中,所以当并行扩展代码运行时,它会尝试从池中抓取许多线程并使其饥饿(或者由于2个线程不可用而抓取较少的线程)。如果不使用一些诊断工具深入挖掘,我真的说不出来。我看不出这两个部分是如何相互关联的。这个问题没有很好地提出。是的,各部分之间没有关联,我只是在这里和那里添加了一些关于线程和检查代码如何工作的代码,但事实是,当上述两个线程完成任务时,它们如何影响t
class Program
{
    [ThreadStatic]
    static int thStaticInt = 0;
    static void Main(string[] args)
    {

        //new Thread(() =>
        //{
        //    for (int i = 0; i < 10; i++)
        //    {
        //        thStaticInt++;
        //        Console.WriteLine("from first {0}", thStaticInt);

        //    }
        //}

        //).Start();


        //new Thread(() =>
        //{

        //    for (int i = 0; i < 10; i++)
        //    {
        //        thStaticInt++;
        //        Console.WriteLine("from second {0}", thStaticInt);

        //    }


        //}

        //).Start();


        //Console.WriteLine("Press any key");
        //Console.ReadLine();
       //Another section starts here

        IEnumerable<int> numbers = Enumerable.Range(3, 1000000);
        Stopwatch watch = new Stopwatch();
        watch.Start();
        var primes = from n in numbers.AsParallel()
                     where Enumerable.Range(2, (int)Math.Sqrt(n)).All(i => n % i != 0)
                     select n;

        IEnumerable<int> primeNumbers = primes.ToArray();

        watch.Stop();
        TimeSpan ts = watch.Elapsed;             

        Console.WriteLine("Time Elapsed {0}", ts.Ticks);           

        Console.ReadLine(); 
    }
}