【问题标题】:Lowering Thread Max Stack Size Below 256KB将线程最大堆栈大小降低到 256KB 以下
【发布时间】:2019-03-13 16:55:43
【问题描述】:

是否可以在 Windows 服务器上运行的 C# 中创建最大堆栈大小低于 256KB 的线程? -- 或者 IIS 的默认值;或更具体地说,Azure 网站

我编写的这个控制台程序似乎表明它不能通过 .NET Thread 构造函数实现,而且我在网络上没有找到任何信息表明它可以通过 P-Invoke 或任何其他机制实现。

这是我的 Windows 10 桌面上的程序输出:

默认最大堆栈大小(以字节为单位):1,048,576
预期的最大堆栈大小(以字节为单位):64,000;实际:262,144
预期的最大堆栈大小(以字节为单位):128,000;实际:262,144
预期的最大堆栈大小(以字节为单位):512,000;实际:524,288
预期的最大堆栈大小(以字节为单位):2,048,000;实际:2,097,152
预期的最大堆栈大小(以字节为单位):1,024,000;实际:1,048,576

internal class Program
{
  public static void Main()
  {
    var threads = new[]
    {
      CreateControlThread(),
      CreateThread(64_000),
      CreateThread(128_000),
      CreateThread(512_000),
      CreateThread(1_024_000),
      CreateThread(2_048_000)
    };

    foreach (var thread in threads) thread.Start();
    foreach (var thread in threads) thread.Join();

    Console.ReadKey();
  }

  private Thread CreateControlThread()
     => new Thread(() => WriteMaximumStackSize(0));

  private static Thread CreateThread(int maximumStackSizeInBytes)
     => new Thread(() => WriteMaximumStackSize(maximumStackSizeInBytes), maximumStackSizeInBytes);

  private static void WriteMaximumStackSize(int expected)
  {
    GetCurrentThreadStackLimits(out uint low, out uint high);

    if (expected > 0)
    {
      Console.WriteLine("Expected maximum stack size in bytes: " + expected.ToString("n0") + "; Actual: " + (high - low).ToString("n0"));
    }
    else
    {
      Console.WriteLine("Default maximum stack size in bytes: " + (high - low).ToString("n0"));
    }
  }

  [DllImport("kernel32.dll")]
  private static extern void GetCurrentThreadStackLimits(out uint lowLimit, out uint highLimit);
}

【问题讨论】:

  • 问显而易见的......你为什么要这样做?看看:docs.microsoft.com/en-us/windows/desktop/ProcThread/….
  • 感谢您的链接。那么,似乎没有办法在 C# 中严格设置它。这也很有趣:“操作系统将指定大小四舍五入到最接近系统分配粒度的倍数(通常为 64 KB)”。所以 64KB 将是我可以去的最小的。至于“为什么”的问题,我无法提供细节。请放心,我不会尝试对我的代码进行一些巧妙的优化,它与安全性无关。如果你把你的评论变成一个答案,我会标记它。
  • 不,CLR 强制要求最小为 256KB。重要的是,它不仅被您的程序使用。抖动和操作系统也使用它。空间不足总是会立即致命的。
  • 为什么投反对票?这是一个完全合理的问题。不要仅仅因为我在询问,就认为我做出了错误的决定或者我不理解这样做的后果。
  • @HansPassant 感谢您的回答,这解释了它。我能够创建一个小于 256KB 的新线程(不是池化,不是模块级)的原因是无关紧要的。重要的是要知道,这是不可能的。再次感谢。

标签: c# windows azure-web-app-service


【解决方案1】:

看看Thread Stack Size docs on Microsoft.com

特别是,默认堆栈大小在PE Header(EXE文件的头部)中设置。您可能会找到一种方法来 P/Invoke 对可以操纵堆栈大小的本机线程创建调用的适当调用,但我不知道您如何将 .NET 线程对象附加到这样的本机线程。

我什至无法想象您可以为线程池线程执行此操作。

您可能会四处寻找其他人的线程库。可能有适合您需求的东西。我知道我已经成功使用了第三方线程池库(但我不记得有任何“自带线程”功能)。

【讨论】:

  • this question 的答案中的一些附加信息。
  • 嘿,谁对我投了反对票……我意识到这不是一个非常完整的答案,但我把它放在那里是为了回应 OP 说“如果你把你的评论变成我的答案”会标记它”。
  • 答案已经足够好了。不过要明确一点,我不是为池线程或整个模块执行此操作。根据我的问题,我在问如何创建一个最大堆栈大小小于 256KB 的新线程
猜你喜欢
  • 2011-07-27
  • 2011-05-08
  • 1970-01-01
  • 2016-04-06
  • 2011-11-24
  • 2010-09-15
  • 2021-02-11
  • 2011-02-02
相关资源
最近更新 更多