c++ - Windows 服务生成的进程运行速度比 GUI 生成的进程慢 3 到 4 倍

标签 c++ windows service macros

我用 Borland C++ 编写了一个服务应用程序。它工作正常。在 ServiceStart(TService *Sender,bool &Started) 例程中,我调用 mjwinrun 来启动一个进程,该进程拾取并处理宏。此过程没有 UI,任何错误都会记录到文件中。它会继续运行,直到服务器重新启动、关闭或使用任务管理器终止进程。这是 mjwinrun :-

int mjwinrun(AnsiString cmd)
{
  STARTUPINFO mjstupinf; PROCESS_INFORMATION mjprcinf;
  memset(&mjstupinf,0,sizeof(STARTUPINFO)); mjstupinf.cb=sizeof(STARTUPINFO);
  if (!CreateProcess(NULL,cmd.c_str(),NULL,NULL,TRUE,0,NULL,GetCurrentDir().c_str(),&mjstupinf,&mjprcinf))
  {
    LogMessage("Could not launch "+cmd); return -1;
  }
  CloseHandle(mjprcinf.hThread); CloseHandle(mjprcinf.hProcess);
  return mjprcinf.dwProcessId;
}

cmd 是启动宏队列处理器的命令行。我使用了一个占用大量 CPU/内存的宏,并将其计时写入文件。这是我发现的:-

1) 如果宏处理器是在登录 session 中从命令行启动的,无论它在哪个 Windows 内核下运行,宏都会在 6 秒内完成。

2) 如果宏处理器是从在 Vista 核心或更早版本上启动的服务启动的(使用上面的 mjwinrun),宏将在 6 秒内完成。

3) 如果宏处理器是从在 Windows 7 内核或更高版本上启动的服务启动的(使用上面的 mjwinrun),宏将在 18 秒以上完成。

我已经为 CreateProcess 尝试了所有不同的标志,但没有一个有什么不同。我已经尝试了该服务的所有不同帐户,但没有任何区别。我尝试为任务、I/O 和页面设置所有各种优先级,但它们都没有区别。就好像服务的派生进程以某种方式受到限制,不是在 I/O 方面,而是在 CPU/内存使用方面。有什么想法在 Windows 7 之后发生了变化吗?

最佳答案

我隔离了代码来重现它,它最终归结为调用数据库引擎来查找字段定义(TTable 方法 FindField 和 FieldByName)。当在服务应用程序而不是 GUI 应用程序上运行时,这些在具有很多字段的表上花费的时间要长得多。我设计了自己的方法来存储从字段名称到字段定义的映射,因为我总是使用中央例程打开数据库。我在每个表上使用了一个由 Tag 属性索引的字符串数组(所有 BCB 对象通用),其中每个字符串由 ;fieldname;fieldnumber; 组成。对,然后对字段名称执行 .Pos 以获取字段编号。 fieldnumber 被零填充到宽度为 4。这只为整个应用程序及其所有数据库使用几百 KB 的 RAM。一旦就位,服务应用程序将以与 GUI 应用程序相同的速度运行。我唯一能想到的可以解释这一点的是,服务应用程序有一个固定的堆(我想我默认在某处读取 48MBytes),用于它们自己和它们产生的任何进程。有很多字段,内存溢出,不得不在磁盘上抖动到 VM。 GUI 应用程序没有这样的限制,并且能够完全在实际内存中进行查找。但是,我也许完全错了。我学到的一件事是 FieldByName 和 FindField 是调用起来很昂贵的 TTable 函数,现在我已经用我自己的机制取代了它们,这似乎工作得更好更快。这是我的查找例程:-

AnsiString fldsbytag[MXSPRTBLS+100];

TField *fldfromtag(TAdsTable *tbl,AnsiString fld)
{
  int fi=fldsbytag[tbl->Tag].Pos(";"+fld.UpperCase()+";"),gi;
  if (fi==0) return tbl->FindField(fld);
  gi=StrToIntDef(fldsbytag[tbl->Tag].SubString(fi+fld.Length()+2,4),-1);
  if (gi<0 || gi>=tbl->Fields->Count) return tbl->FindField(fld);
  return tbl->Fields->Fields[gi];
}

关于c++ - Windows 服务生成的进程运行速度比 GUI 生成的进程慢 3 到 4 倍,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35043542/

相关文章:

c++ - OpenGL : Strange behaviour 中的 OpenCV 图像

windows - 打开远程机器的 Windows C 驱动器

java - 将唯一的文件扩展名扫描到变量中

windows - 来自网络URL的DirectShow RenderFile具有严重缺陷。如何避免呢?

android - 与前台服务android通信

elasticsearch - 如何使用Brew将Elasticsearch作为服务安装

java - 适当使用一个servlet?

c++ - 拦截套接字函数(Windows)

C++:数字与位?

c++ - 如果右值引用确实需要 std::move,我们应该什么时候声明它们?