Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/322.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#中的线程睡眠(1)有什么影响?_C#_Multithreading - Fatal编程技术网

C#中的线程睡眠(1)有什么影响?

C#中的线程睡眠(1)有什么影响?,c#,multithreading,C#,Multithreading,在windows窗体应用程序中,调用Thread.Sleep(1)会产生什么影响,如以下代码所示: public Constructor() { Thread thread = new Thread(Task); thread.IsBackground = true; thread.Start(); } private void Task() { while (true) { // do something Thread.

在windows窗体应用程序中,调用
Thread.Sleep(1)
会产生什么影响,如以下代码所示:

public Constructor()
{
    Thread thread = new Thread(Task);
    thread.IsBackground = true;
    thread.Start();
}

private void Task()
{
    while (true)
    {
        // do something
        Thread.Sleep(1);
    }
}
这个线程会占用所有可用的CPU吗


我可以使用什么评测技术来测量此线程的CPU使用率(任务管理器除外)?

不,它不会占用CPU,它只会暂停线程至少那么长时间。当线程暂停时,操作系统可以安排另一个不相关的线程来使用处理器。

不,它不会占用所有可用的CPU,因为当另一个线程有工作要做时,操作系统的调度程序将关闭休眠线程。

不,它不会。你几乎看不到。在每秒不到1000次的某个地方,这个线程会在再次睡觉之前醒来,几乎什么都不做

编辑:

我必须检查一下。此测试在Java1.5上运行

@Test
public void testSpeed() throws InterruptedException {
    long currentTime = System.currentTimeMillis();
    int i = 0;
        while (i < 1000)
        {
            Thread.sleep(1);
            i++;
        }
    System.out.println("Executed in " + (System.currentTimeMillis() - currentTime));
}
@测试
public void testSpeed()引发InterruptedException{
长currentTime=System.currentTimeMillis();
int i=0;
而(i<1000)
{
睡眠(1);
i++;
}
System.out.println(“在”+(System.currentTimeMillis()-currentTime)中执行);
}

在我的3ghz机器上以每秒大约500次睡眠的速度运行。我想C#应该大致相同。我想有人会用这个非常重要的现实基准的C#数字来报告。顺便说一下,没有可观察到的CPU使用情况。

如前所述,您的循环不会占用CPU

但是要注意:Windows不是一个实时操作系统,所以你将每秒从线程中唤醒1000次。如果您没有设置最低分辨率,您将大约每15毫秒醒来一次。即使您将最低分辨率设置为1毫秒,您仍然只会每3-4毫秒醒来一次


为了获得毫秒级计时器粒度,您必须使用Win32 multimedia timer()。

一个线程一次最多占用一个(逻辑)CPU。而1毫秒的睡眠也不会让人心烦意乱。不要紧张。

线程。如上所述的睡眠(1)不会占用CPU

以下是线程休眠(或多或少)时发生的情况:

  • Sleep被转换成一个系统调用,这反过来会触发一个陷阱(一种允许操作系统控制的中断)
  • 操作系统检测到对睡眠的调用,并将线程标记为阻塞
  • 操作系统内部保存了一个需要唤醒的线程列表,以及何时唤醒
  • 由于线程不再使用CPU,操作系统
  • 如果父进程没有用完所有的时间片,操作系统将安排进程的另一个线程执行
  • 否则,另一个进程(或空闲进程)将开始执行
  • 当时间到期时,您的线程将再次被安排执行,这并不意味着它将自动开始执行
最后一点,我不知道你到底在做什么,但你似乎在尝试扮演调度程序的角色,也就是说,睡眠为CPU提供了做其他事情的时间


在少数情况下(事实上很少),这可能是正确的,但大多数情况下,您应该让调度程序完成它的工作,它可能比您知道的更多,并且可以使工作比您做的更好,正如Bob Nadler提到的
线程。睡眠(1)
不能保证1ms的睡眠时间

下面是一个使用Win32多媒体定时器强制睡眠1ms的示例

    [DllImport("winmm.dll")]
    internal static extern uint timeBeginPeriod(uint period);
    [DllImport("winmm.dll")]
    internal static extern uint timeEndPeriod(uint period);

    timeBeginPeriod(1);
    while(true)
    {
        Thread.Sleep(1); // will sleep 1ms every time
    }
    timeEndPeriod(1);
在一个C#GUI应用程序中测试这一点,我发现该应用程序占用了我大约50%的CPU

有关此主题的更多讨论,请参阅以下论坛帖子:


这是一个旧线程,在我的很多搜索中都会出现,但是Win7有一个新的调度程序,并且它的行为似乎与上面的不同

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            DateTime dtEnd = DateTime.Now.AddSeconds(1.0);
            int i = 0;
            while (DateTime.Now < dtEnd)
            {
                i++;
                Thread.Sleep(1);
            }

            Console.WriteLine(i.ToString());

            i = 0;
            long lStart = DateTime.Now.Ticks;
            while (i++ < 1000)
                Thread.Sleep(1);

            long lTmp = (DateTime.Now.Ticks - lStart) / 10000;

            Console.WriteLine(lTmp.ToString());

            Console.Read();
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
使用系统线程;
命名空间控制台应用程序2
{
班级计划
{
静态void Main(字符串[]参数)
{
DateTime dtEnd=DateTime.Now.AddSeconds(1.0);
int i=0;
while(DateTime.Now
根据上面的代码,我的第一个结果是946。因此,在1秒的时间内使用1ms睡眠,我得到了946次唤醒。这非常接近1ms

第二部分询问以1ms的速度进行1000次睡眠事件需要多长时间。我有1034M。同样,接近1ms

这是在使用.NET4.0的1.8ghz core2duo+Win7上实现的


编辑:记住,睡眠(x)并不意味着在这个时候醒来,它意味着不早于这个时间叫醒我。这不是保证。尽管如此,您可以提高线程的优先级,Windows应该在低优先级线程之前安排线程。

还可以查看以下内容:

使用系统;
使用系统诊断;
使用System.Runtime.InteropServices;
使用系统线程;
名称空间测试
{
公共静态类程序
{
公共静态void Main(字符串[]args)
{
秒表sw=新秒表();
对于(int i=0;i<10;++i)
{
sw.Reset();
sw.Start();
睡眠(50);
sw.Stop();
Console.WriteLine(((默认)睡眠时间为“+sw.elapsedmillyses”);
TimeBeginPeriod(1);
sw.Reset();
sw.Start();
睡眠(50);
sw.Stop();
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;

namespace Test
{
    public static class Program
    {
        public static void Main(string[] args)
        {
            Stopwatch sw = new Stopwatch();

            for (int i = 0; i < 10; ++i)
            {
                sw.Reset();
                sw.Start();
                Thread.Sleep(50);
                sw.Stop();

                Console.WriteLine("(default) Slept for " + sw.ElapsedMilliseconds);

                TimeBeginPeriod(1);
                sw.Reset();
                sw.Start();
                Thread.Sleep(50);
                sw.Stop();
                TimeEndPeriod(1);

                Console.WriteLine("(highres) Slept for " + sw.ElapsedMilliseconds + "\n");
            }
        }

        [DllImport("winmm.dll", EntryPoint="timeBeginPeriod", SetLastError=true)]
        private static extern uint TimeBeginPeriod(uint uMilliseconds);

        [DllImport("winmm.dll", EntryPoint="timeEndPeriod", SetLastError=true)]
        private static extern uint TimeEndPeriod(uint uMilliseconds);
    }
}