Thread.Sleep(0) 未按预期工作 [duplicate]

Thread.Sleep(0) is not working as expected [duplicate]

提问人:Amitava Karan 提问时间:11/8/2013 更新时间:11/8/2013 访问量:366

问:

我刚刚开始学习“C#中的线程”。 我在一本书中发现 Thread.Sleep(0) 会立即自愿放弃线程的当前时间片 将 CPU 移交给其他线程。

当我写了几行代码来测试它时。我没有得到预期的结果。这是我写的代码。

class Program
{
    static void Main(string[] args)
    {
        Thread.CurrentThread.Name = "Thread A(main thread)";

        Thread thread = new Thread(PrintNumber);
        thread.Name = "Thread B";
        thread.Start();

        for (int i = 0; i < 40; i++)
        {
            Console.WriteLine("{0} | i = {1}", Thread.CurrentThread.Name, i);
        }
    }

    void PrintNumber()
    {
        for (int i = 0; i < 40; i++)
        {
            Console.WriteLine("{0} | i = {1}", Thread.CurrentThread.Name, i);

            if (i == 4)
            {
                Thread.Sleep(0);
            }
        }
    }
}

根据我的理解,这将在线程 B 中打印多达 4 个,然后它将恢复线程 A。下一个线程计划是不可预测的。 但这并没有发生。虽然第一次使用线程 B,但有时它最多打印 6 个,有时 8 个意味着完全不可预测。

那么我对Theread.Sleep(0)的概念是错误的吗?有人可以澄清一下这个概念吗?

C# 多线程处理

评论

0赞 Amitava Karan 11/8/2013
我在搜索时发现了这个线程。我忽略了它,认为它描述了不同的问题。现在我看到它问的问题几乎和我的问题一样。对不起,重复了。

答:

3赞 Marc Gravell 11/8/2013 #1

如果它确实释放了线程的切片,这并不意味着你可以预测它要去的地方 - 它可以转到计算机上的任何进程。特别是,假设您有一台多核计算机,则另一个线程可能完全由另一个内核提供服务。在如图所示的代码中,也可能直到 的循环接近时才开始。启动线程不是即时的。"Thread B"Main

很少有场景会对你有用,所有这些场景都涉及线程和内存模型的广泛知识。Thread.Sleep(0)

评论

0赞 Amitava Karan 11/8/2013
当我在线程中使用 Thread.Sleep(0) 时,我无法预测哪个线程将获得时间片。但是,可以再次获得时间片的同一线程吗?
0赞 Marc Gravell 11/8/2013
@amitavak当然,为什么不呢?
2赞 Michael Mairegger 11/8/2013 #2

Thread.Yield()确保正在执行的下一个线程不是当前线程。

评论

0赞 Amitava Karan 11/8/2013
我相信 Thread.Sleep(0) 做同样的事情。唯一的区别是 Thread.Yield() 将仅将时间片让给在同一处理器上运行的线程。
0赞 Moho 11/8/2013
极有可能,但不能保证。这就是为什么返回一个Thread.Yield()bool
0赞 Amitava Karan 11/8/2013
好点子。我没有注意到。谢谢。