当在单核 CPU 上创建多个线程时会发生什么?

huangapple go评论97阅读模式
英文:

What happens when I create several threads with a single core CPU?

问题

假设我有一个运行两个任务的应用程序。

如果我们只有一个核心的 CPU,会发生什么情况?只有一个任务会运行吗?第二个任务会等待第一个线程可用吗?

编辑:假设任务2依赖于任务1先完成。在单核 CPU 上,这种情况是否总是成立?

第一个任务会在第二个任务之前运行吗?

英文:

Let's say I have an application that has two tasks running.

    TriggerHour1 = new TimeSpan(0, 1, 0);
    Task.Run(async () => 
    {
        while (true)
        {
            var triggerTime = DateTime.Today + TriggerHour1 - DateTime.Now;
            if (triggerTime < TimeSpan.Zero)
                triggerTime = triggerTime.Add(new TimeSpan(24, 0, 0));
            await Task.Delay(triggerTime);
            Console.WriteLine("RunningTask1 finished")
        }
    });

    TriggerHour2 = new TimeSpan(0, 1, 0);
    Task.Run(async () => 
    {
        while (true)
        {
            var triggerTime = DateTime.Today + TriggerHour2 - DateTime.Now;
            if (triggerTime < TimeSpan.Zero)
                triggerTime = triggerTime.Add(new TimeSpan(24, 0, 0));
            await Task.Delay(triggerTime);
            Console.WriteLine("RunningTask2 finished")
        }
    });

What happenes if we have a CPU with only one core? Will only one task run? Will the second tasks wait for the first thread to be available?

Edit: Let's say that Tasks 2 relies on Task 1 to be completed first. Will this always be the case on a single Core CPU?

    int counter = 0;
    TriggerHour1 = new TimeSpan(0, 1, 0);
    Task.Run(async () => 
    {
        while (true)
        {
            var triggerTime = DateTime.Today + TriggerHour1 - DateTime.Now;
            if (triggerTime < TimeSpan.Zero)
                triggerTime = triggerTime.Add(new TimeSpan(24, 0, 0));
            await Task.Delay(triggerTime);
            Console.WriteLine("RunningTask1 finished");
            counter += 100;
            Console.WriteLine(counter);
        }
    });

    TriggerHour2 = new TimeSpan(0, 1, 0);
    Task.Run(async () => 
    {
        while (true)
        {
            var triggerTime = DateTime.Today + TriggerHour2 - DateTime.Now;
            if (triggerTime < TimeSpan.Zero)
                triggerTime = triggerTime.Add(new TimeSpan(24, 0, 0));
            await Task.Delay(triggerTime);
            Console.WriteLine("RunningTask2 finished");
            Console.WriteLine(counter);
        }
    });

Will the first Task always run before?

答案1

得分: 5

首先,Task并不总是意味着有一个线程(参见Stephen Cleary的《There Is No Thread》),实际上在这种情况下,理论上可以由一个线程来处理(由于await Task.Delay(triggerTime))。

至于单核CPU上的线程 - 多线程可以在单处理器系统上实现,操作系统会根据调度策略来安排它们的执行顺序,参考自https://stackoverflow.com/questions/16116952/can-multithreading-be-implemented-on-a-single-processor-system:

> 在单处理器系统中,多个线程会依次执行,或者等待一个线程完成或被操作系统抢占,具体取决于线程的优先级和操作系统的策略。但是运行中的线程会给人一种它们同时运行的错觉,相对于用户空间应用程序的响应时间。

此外,还有一些硬件实现,比如Intel的超线程技术,可以在一个物理核心上模拟多个(通常是2个)逻辑核心。

> 第二个任务可以在第一个任务之前执行吗?

可以。

> 假设任务2依赖于任务1先完成,那在单核CPU上是否总是如此?

如果两个并行进程(线程、任务等)之间存在相互依赖关系,你需要使用适当的同步机制(参见同步原语的概述),有太多的因素会影响结果 - 线程池、操作系统调度器,在你的情况下还有系统时钟,有时还有内存模型(https://stackoverflow.com/questions/39062100/how-does-cpu-reorder-instructions,内存排序)。

例如,counter += 100;不是一个线程安全的操作,如果多个线程对counter进行更新,可能会得到意想不到的结果。

英文:

First of all Task does not always mean there is a thread (see the There Is No Thread by Stephen Cleary), actually in this case both in theory can be served by one thread (due to await Task.Delay(triggerTime)).

As for threads on single core CPU - multithreading can be implemented on a single processor system, it is up for the OS how to schedule them, from https://stackoverflow.com/questions/16116952/can-multithreading-be-implemented-on-a-single-processor-system:

> In a single-processor system, multiple threads execute , one after the other or wait until one thread finishes or is preempted by the OS , depending on the thread priority and the OS policy.But the running threads , gives an illusion that they run simultaneous , relative to the required application response time of the User space application.

Also there are some hardware implementations like Intel's Hyper-threading which allows simulating multiple (usually 2) logical cores per one physical.

> Could the second Tasks be executed before?

Yes.

> Let's say that Tasks 2 relies on Task 1 to be completed first. Will this always be the case on a single Core CPU?

If you have interdependencies between two parallel processes (threads, tasks, whatever) you need to use appropriate synchronization (see the overview of synchronization primitives), there are too many moving parts which can affect thigs - thread pool, OS scheduler, in your case system clock, in some cases memory model (https://stackoverflow.com/questions/39062100/how-does-cpu-reorder-instructions, memory ordering)

For example counter += 100; is not a thread safe operation and if multiple threads perform updates to counter you can encounter quite unexpected results.

huangapple
  • 本文由 发表于 2023年7月27日 17:59:08
  • 转载请务必保留本文链接:https://go.coder-hub.com/76778588.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定