multithreading - 为什么即使在抢占式多任务操作系统 (Windows 7) 上线程也会饥饿

标签 multithreading delphi winapi delphi-7 multitasking

我编写了一个 Win32 应用程序(在 Delphi-7 中,它是使用 TThread 类的 32 位)来创建 100 个线程。每个线程在恢复时将连续(在循环中)递增与线程对象关联的 64 位计数器(因此不会锁定或共享数据)。

如果让系统运行 10 到 15 秒,然后停止,您应该会在每个线程中看到大致相同的计数。但我观察到,81 个线程运行了 4 亿次循环,其余线程的循环次数超过 9.5 亿次。最慢的线程仅获得 2.3 亿,而最快的线程则为 21.11 亿。

根据 MSDN,抢占式多任务处理是在线程级别(而不是进程级别),因此我的每个线程都应该以循环方式获得其时间片。我在这里缺少什么以及为什么会出现这种差异?

Edit1:机器配置:Intel i7 四核 3.4GHz,开启超线程(一次 8 个事件线程)。运行 Windows-7 64 位专业版(测试应用程序为 32 位)

Edit2(线程代码):测试应用程序是在打开优化的情况下构建的,没有任何调试信息。在 IDE 外部运行测试应用程序。

type

  TMyThread = class(TThread)
  protected
    FCount: Int64;
  public
    constructor Create;
    procedure Execute; override;
    property Count: Int64 read FCount;
  end;


{ TMyThread }

constructor TMyThread.Create;
begin
  inherited Create(True);
  FCount := 0;
end;  

procedure TMyThread.Execute;
begin
  inherited;
  while not Terminated do
  begin
    Inc(FCount);
  end;
end;

最佳答案

循环调度对于内核来说是一个明显的策略。然而,这并不是 Windows 调度程序的工作方式。在 Windows 9x 时代,它曾经是一个调度程序,非常能够为各种虚拟机提供相同的时间。但在 Dave Cutler 团队发起的 NT 分支中情况并非如此,调度纯粹基于优先级

任何具有最高优先级的线程都会获得CPU。 Windows 中还有另一 block 代码可以修改线程的优先级,修改线程创建时获得的默认优先级。该代码知道诸如拥有前台窗口的线程之类的东西。或者等待收到信号的同步对象的线程。或者尝试解决优先级反转问题的更奇怪的调度问题。随机给线程一个运行的机会,即使它还没有轮到。

首先专注于编写合理的代码。启动一百个线程并不是一件非常明智的事情。您正在尝试消耗机器实际上不可用的资源,没有人拥有具有一百个核心的机器。然而。 2 的幂,首先获得 128 核的机器。

关于multithreading - 为什么即使在抢占式多任务操作系统 (Windows 7) 上线程也会饥饿,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11942827/

相关文章:

c++ - 具有相同编译器的相同程序代码会导致不同的二进制文件

c# - 等待任何线程完成,而不是全部

mysql - 提交 MySql + Zeos lib

delphi - 检测数组中唯一值的数量

c++ - 在弹出窗口中管理 CEF 客户区的窗口消息

multithreading - Postgres 9.3 中 SELECT FOR UPDATE 的并发问题

multithreading - 如何优化Grails构建和测试执行速度?

c++ win32防止上下文菜单关闭

delphi - Delphi代码编辑器中这个图标是什么意思?

c# - lpr 命令在 Win 7 中的 C# 程序中不起作用