由Windows服务生成的进程比GUI

时间:2016-01-27 16:59:49

标签: 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)如果在登录的会话中从命令行启动宏处理器,无论它在哪个Windows核心上运行,宏都会在6秒内完成。

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

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

我已经为CreateProcess尝试了所有不同的标志,但它们都没有区别。我已经尝试了所有不同的服务帐户,这没有任何区别。我尝试为任务,I / O和Page设置所有各种优先级,但它们都没有区别。这就好像服务的衍生进程受到某种程度的限制,而不是I / O术语,而是CPU /内存使用条件。任何想法在Windows 7以后发生了什么变化?

2 个答案:

答案 0 :(得分:1)

我隔离了代码来重现这一点,它最终归结为调用数据库引擎来查找字段定义(TTable方法FindField和FieldByName)。当在服务应用程序而不是GUI应用程序上运行时,这些在具有大量字段的表上花费的时间更长。我设计了自己的方法来存储从字段名称到字段定义的映射,因为我总是使用中央例程打开我的数据库。我在每个表上使用了一个由Tag属性索引的字符串数组(对所有BCB对象都是通用的),其中每个字符串由; fieldname; fieldnumber;对,然后做一个.Pos的字段名称来获取字段编号。 fieldnumber是零填充到宽度4.这仅对整个应用程序及其所有数据库使用几百KB的RAM。一旦到位,服务应用程序以与GUI应用程序相同的速度运行。我能想到的唯一可以解释这一点的是,服务应用程序有一个固定的堆(我认为我默认在某处读取了48MB)用于自己和它们产生的任何进程。由于存在大量字段,因此内存溢出并且不得不在磁盘上发生故障。 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];
}

答案 1 :(得分:0)

如果没有更多细节,很难给出这个问题的权威答案。

然而,需要考虑的一个因素是所描述的Windows前台优先级提升here

您可能想阅读Russinovich关于进程/线程的书籍章节,特别是有关调度的内容。你可以在网上找到这本书的PDF文件(这两本书共同构成了整本书)。我相信最新版本(或最新版本)涵盖了Win 7的变化。