Mes*_*ros 3 .net c# multithreading .net-core
因此,我正在根据以下书籍学习 .NET Thread 类:Exam Ref 70-483: Programming in C#,我注意到一些我不知道为什么会发生或是否应该发生的事情。
这本书在第 4 页给了我这部分代码:
public static class Program
{
public static void ThreadMethod()
{
for (int i = 0; i < 10; i++)
{
Console.WriteLine("ThreadProc: {0}", i);
Thread.Sleep(0);
}
}
public static void Main()
{
Thread t = new Thread(new ThreadStart(ThreadMethod));
t.Start();
for (int i = 0; i < 4; i++)
{
Console.WriteLine("Main thread: Do some work.");
Thread.Sleep(0);
}
t.Join();
}
}
Run Code Online (Sandbox Code Playgroud)
预期结果如下所示,因为在每个 Thread.Sleep(0) 处,当前线程退出并继续处理队列中的下一个线程:
// Main thread: Do some work.
// ThreadProc: 0
// Main thread: Do some work.
// ThreadProc: 1
// Main thread: Do some work.
// ThreadProc: 2
// Main thread: Do some work.
// ThreadProc: 3
// ThreadProc: 4
// ThreadProc: 5
// ThreadProc: 6
// ThreadProc: 7
// ThreadProc: 8
// ThreadProc: 9
Run Code Online (Sandbox Code Playgroud)
但是当我构建我的这个版本时,它没有按预期工作,即使我复制粘贴代码并在我的机器上运行,每次执行程序时它都会给出这个结果,上面的代码相同:
// Main thread: Do some work.
// ThreadProc: 0
// ThreadProc: 1
// ThreadProc: 2
// ThreadProc: 3
// ThreadProc: 4
// ThreadProc: 5
// ThreadProc: 6
// ThreadProc: 7
// ThreadProc: 8
// ThreadProc: 9
// Main thread: Do some work.
// Main thread: Do some work.
// Main thread: Do some work.
Run Code Online (Sandbox Code Playgroud)
如您所见,它似乎进入了副线程,当我调用 Thread.Sleep(0) 方法时,它不会像它应该的那样返回主线程,而是继续在副线程上工作直到它完成。
作为一种解决方法,我使用 Random 类生成一个 100 到 500 之间的随机数以传递给 Thread.Sleep() 方法,它开始按预期工作:
public static class Program
{
public static void ThreadMethod()
{
var rand = new Random();
for (int i = 0; i < 10; i++)
{
Console.WriteLine("ThreadProc: {0}", i);
Thread.Sleep(rand.Next(100, 500));
}
}
public static void Main()
{
Thread t = new Thread(new ThreadStart(ThreadMethod));
t.Start();
var rand = new Random();
for (int i = 0; i < 4; i++)
{
Console.WriteLine("Main thread: Do some work.");
Thread.Sleep(rand.Next(100, 500));
}
t.Join();
}
}
Run Code Online (Sandbox Code Playgroud)
结果如下所示:
// Main thread: Do some work.
// ThreadProc: 0
// ThreadProc: 1
// ThreadProc: 2
// Main thread: Do some work.
// ThreadProc: 3
// Main thread: Do some work.
// ThreadProc: 4
// Main thread: Do some work.
// ThreadProc: 5
// ThreadProc: 6
// ThreadProc: 7
// ThreadProc: 8
// ThreadProc: 9
Run Code Online (Sandbox Code Playgroud)
我不认为这本书是在 .NET Core 框架上写的,我认为这个“问题”可能是这两个框架之间同步上下文的变化引起的。我检查了两个线程的优先级并设置为默认的“正常”。
任何人都知道为什么会发生这种情况?
对于此示例,您不会看到 .net 框架和 .net 核心之间的任何行为差异。
这本书是在大多数消费级 CPU 是单核的时代写成的。对于单核 CPU,一次只能调度一个线程,因此样本的输出是可预测的。
现在,几乎所有的 CPU 都有多个内核,这意味着可以同时调度多个线程。这使得程序的输出不可预测,并且不受调用的影响Thread.Sleep(0)。
获得本书关于现代硬件的行为的一种方法是设置进程的亲和性,使其在单核上运行:
> start /affinity 1 CoreConsoleApp1.exe
Run Code Online (Sandbox Code Playgroud)
通过这样做,我得到了预期的交错输出:
ThreadProc: 0
Main thread: Do some work.
ThreadProc: 1
Main thread: Do some work.
ThreadProc: 2
Main thread: Do some work.
ThreadProc: 3
Main thread: Do some work.
ThreadProc: 4
ThreadProc: 5
ThreadProc: 6
ThreadProc: 7
ThreadProc: 8
ThreadProc: 9
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
121 次 |
| 最近记录: |