2

我有一个程序,我想只在一个 CPU 上运行,这样它就不会占用太多系统资源。问题是,它调用了一个自动使用所有可用 CPU 内核的外部 DLL。我没有外部 DLL 的源代码。如何将 DLL 限制为仅使用一个 CPU?

编辑:感谢您的帮助,这是我用来限制一个 CPU(Windows)的代码:

// Limit the process to only 1 thread so we don't chew up system resources
HANDLE ProcessHandle = GetCurrentProcess();
DWORD ProcessAffinityMask;
DWORD SystemAffinityMask;
if(GetProcessAffinityMask(ProcessHandle,&ProcessAffinityMask,&SystemAffinityMask)
    && SystemAffinityMask != 0)
{
    // Limit to 1 thread by masking all but 1 bit of the system affinity mask
    DWORD NewProcessAffinityMask = ((SystemAffinityMask-1) ^ SystemAffinityMask) & SystemAffinityMask;
    SetProcessAffinityMask(ProcessHandle,NewProcessAffinityMask);
}

编辑:事实证明,Brannon 设置进程优先级的方法更适合我想要的,即防止进程占用资源。这是该代码(Windows):

// Make the process low priority so we don't chew up system resources
HANDLE ProcessHandle = GetCurrentProcess();
SetPriorityClass(ProcessHandle,BELOW_NORMAL_PRIORITY_CLASS);
4

6 回答 6

9

您可以设置程序的 CPU 亲和性。在 Windows 上尝试SetProcessAffinityMask函数或在 Linux上尝试sched_setaffinity 。

于 2009-02-07T07:35:12.090 回答
5

设置处理器亲和性是错误的方法。让操作系统处理调度。

如果机器处于空闲状态,您希望尽可能多地使用处理器。否则你会无缘无故地做更少的工作。如果机器很忙,那么您希望利用“空闲”周期而不会对其他进程产生不利影响。

Windows 内置了此功能。正确的解决方案是设置进程的基本优先级。

有关. _ _SetPriorityClass()

如果您想在不编写任何代码的情况下对此进行测试,请使用任务管理器更改进程的优先级。

于 2009-02-07T08:56:14.207 回答
1

通常,dll 与调用它的代码位于同一线程/内存空间中。调用 DLL 本身的行为不应创建线程。如果调用 DLL 似乎会创建更多线程,则意味着 DLL 本身正在其代码的某处创建线程。如果您没有 DLL 的任何源代码或文档,则您无能为力(如果您希望 DLL 完成它的工作,那么您无需为此做太多事情)。

您可以尝试使用应用程序的优先级 - 将其设置为低可能会改变 CPU 使用率,即使它不会改变创建的线程。但是,您真正想要的似乎是获取此野兽的文档。在不知道代码如何工作的情况下,一般来说,您无法改变它的工作方式。没有超级天才可以改变这一点。

于 2009-02-07T07:39:10.977 回答
0

呃……为什么?说真的,您为什么要限制能够以这种方式为您提供额外性能的库?您是否尝试访问共享资源或其他东西?有人会认为多线程库能够安全地处理这个问题。

除非您没有提及某些内容,否则我看不出有任何正当理由可以尝试将多线程库限制为单个线程。

于 2009-02-07T07:36:32.090 回答
0

所以你的程序使用一个线程,但你不希望外部DLL使用多个线程?您对外部 DLL 的功能没有太多控制,但一些方法可能是:

于 2009-02-07T07:36:52.353 回答
0

你没有说这是针对什么平台的。我将在这里假设窗户。

创建子进程并将其与Job Object关联。然后,您可以将该作业对象的处理器关联设置为仅包含一个可用的 CPU 内核。子进程无法将关联掩码更改为不是作业对象的处理器关联子集的任何内容。此外,您应该记住不要对作业设置限制JOB_OBJECT_LIMIT_BREAKAWAY_OK或扩展限制JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK,否则子进程将能够脱离作业。

此外,您可以设置作业的优先级和调度类。也许以较低的 CPU 和/或 IO 优先级创建子进程就足够了?

于 2009-02-07T08:06:02.263 回答