如何将外部DLL限制为一个CPU?

时间:2009-02-07 07:26:11

标签: c++ multithreading dll external-dependencies

我有一个程序,我只想在一个CPU上运行,因此它不会占用太多的系统资源。问题是,它调用外部DLL,自动使用所有可用的CPU内核。我没有外部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);

6 个答案:

答案 0 :(得分:9)

您可以设置程序的CPU亲和力。试试Windows上的SetProcessAffinityMask功能或Linux上的sched_setaffinity

答案 1 :(得分:5)

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

如果机器闲置,您希望尽可能多地使用处理器。否则你无缘无故就会做更少的工作。如果机器繁忙,那么您希望使用“自由”循环而不会对其他过程产生负面影响。

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

有关SetPriorityClass()的详细信息,请参阅http://msdn.microsoft.com/en-us/library/ms686219(VS.85).aspx

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

答案 2 :(得分:1)

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

您可能尝试使用应用程序的优先级 - 将其设置为低可能会更改CPU使用率,即使它不会更改创建的线程。但似乎你真正想要的是为这个野兽获取文档。一般来说,如果不知道代码是如何工作的,那么改变它的工作原理并没有多少办法。没有超级天才可以改变这一点。

答案 3 :(得分:0)

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

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

答案 4 :(得分:0)

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

答案 5 :(得分:0)

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

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

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