2016-01-27 1 views
1

Я написал приложение-сервис в Borland C++. Он работает нормально. В процедуре ServiceStart (TService * Sender, bool & Started) я вызываю mjwinrun для запуска процесса, который обрабатывает и обрабатывает макросы. Этот процесс не имеет интерфейса, и любые ошибки записываются в файл. Он продолжает работать, пока сервер не перезагрузится, не завершите работу или процесс не завершится с помощью диспетчера задач. Вот mjwinrun: -Процесс, порожденный службой Windows, запускается в 3-4 раза медленнее, чем порожден GUI

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/Memory, и заставил его записать свои тайминги в файл. Вот что я нашел:

1) Если макропроцессор запущен из командной строки в сеансе входа в систему, независимо от того, в каком ядре Windows он работает, макрос завершается за 6 секунд.

2) Если макропроцессор запущен из службы, запускающейся на ядре Vista или ранее (используя mjwinrun выше), макрос завершается за 6 секунд.

3) Если макропроцессор запущен из службы, запущенной в ядре Windows 7 или более поздней (используя mjwinrun выше), макрос завершается более чем 18 секунд.

Я пробовал все различные флаги для CreateProcess, и ни один из них не имеет значения. Я пробовал все разные учетные записи для службы, и это не имеет никакого значения. Я попытался установить все приоритеты для задач, ввода/вывода и страницы, но все они не имеют значения. Это как если бы порожденные процессы службы каким-то образом были дросселированы, а не в терминах ввода-вывода, а в терминах использования процессора/памяти. Любые идеи, которые изменились в Windows 7 и далее?

+0

Вряд ли быть ЦП, если система уже не работает. Что на самом деле делает макрос? –

+0

CPU выделяет ядро, когда он выполняет макрос. Он читает в некоторых данных из базы данных и делает некоторую тяжелую обработку, чтобы поместить ее в удобочитаемую форму в текстовый файл вывода (формат CSV). Вы можете видеть, что он читает байты с помощью диспетчера задач, и он читает их в блоках 3 или 4 Кбайт, при случайном всплеске до 400-500 Кбайт за раз каждые 5 секунд. На более быстрой платформе эти всплески происходят каждую секунду. –

+1

Если он максимизирует одно ядро ​​в любом сценарии, то, очевидно, процесс не является дросселируемым ЦП. Возможно, Windows 7 экономит энергию более агрессивно? Ядро процессора, работающее на низкой частоте, является единственным разумным объяснением, которое я могу представить для 100% -18 секунд в одном сценарии, давая вам то же количество фактических вычислений, что и 100% -го-шесть секунд в другом сценарии. –

ответ

1

Я выделил код, чтобы воспроизвести его, и он в конечном итоге сводился к вызовам механизма базы данных для поиска определения поля (методы TTable FindField и FieldByName). Это заняло гораздо больше времени на столе с большим количеством полей при запуске приложения-службы вместо графического интерфейса. Я разработал свой собственный метод для хранения сопоставлений с именами полей в определениях полей, так как я всегда открывал свои базы данных с помощью центральной процедуры. Я использовал массив строк, индексированных свойством Tag в каждой таблице (общий для всех объектов BCB), где каждая строка состояла из: fieldname; fieldnumber; пар, а затем сделал .Pos имени поля, чтобы получить номер поля. Поле fieldnumber равно нулю с шириной 4. Это использует только несколько сотен КБ ОЗУ для всего приложения и всех его баз данных. После этого приложение службы работает с той же скоростью, что и приложение GUI. Единственное, о чем я могу думать, это может объяснить это, что сервисные приложения имеют фиксированную кучу (я думаю, что я по-прежнему читаю 48 Мбайт по умолчанию) для себя и любого процесса, который они порождают. С большим количеством полей память переполнена и должна была превзойти 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]; 
} 
0

Будет очень сложно дать авторитетный ответ на этот вопрос без подробностей.

Однако фактором, который следует учитывать, является повышение приоритета приоритета переднего плана Windows, описанного here.

Возможно, вы захотите прочитать главу книги Руссиновича о процессах/потоках, в частности, о планировании. Вы можете найти PDF-книги книги в Интернете (их две составляющие составляют всю книгу). Я считаю, что последнее (или ближайшее к последнему) издание охватывает изменения в Win 7.

+0

Я уже пробовал флаг повышения приоритета, и это не имело никакого значения. Меня удивляет то, что никто не исследовал это раньше, учитывая, что в сети много жалоб о том, как переходить с XP на Win7, или Windows Server 2003 на Windows Server 2008 R2 замедляет их работу. Я считаю, что это может быть связано с этим. Возможно, Microsoft предвидела множество новых сервисов, добавляемых к их последним предложениям ОС, и дросселированную производительность сервиса, чтобы не создавать приложения GUI вяло. –

+0

Кто-то глубоко это изучил. Марк Руссинович в упомянутой мною книге. Кстати, я не говорил о флаге CreateProcess, скорее я говорил о поведении планировщика. –

Смежные вопросы