IPB
ЛогинПароль:

> Внимание!

1. Пользуйтесь тегами кода. - [code] ... [/code]
2. Точно указывайте язык, название и версию компилятора (интерпретатора).
3. Название темы должно быть информативным.
В описании темы указываем язык!!!

Наладить общение поможет, если вы подпишитесь по почте на новые темы в этом форуме.

2 страниц V  1 2 >  
 Ответить  Открыть новую тему 
> Процессы и "задание", С++ Builder
сообщение
Сообщение #1


Профи
****

Группа: Пользователи
Сообщений: 920
Пол: Женский
Реальное имя: Марина

Репутация: -  2  +


Требуется создать несколько процессов и сгруппировать их в «задание».
И в процессе выполнения у меня возникли некоторые вопросы...

STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si,sizeof(si));
si.cb=sizeof(si);
//Создадим два процесса
CreateProcess
("D:\\WINDOWS\\Lab2.exe",NULL,NULL,NULL,FALSE,0,NULL,NULL,&si,&pi);
CreateProcess
("D:\\Program Files\\Borland\\Delphi7\\Bin\\delphi32.exe",NULL,NULL,NULL,FALSE,0,NULL,NULL,&si,&pi);

SECURITY_ATTRIBUTES sa;
ZeroMemory(&sa,sizeof(sa));
char str[10];
strcpy(str,"Job'\0'");
//Создадим задание
CreateJobObject(&sa,str);
//получим дескриптор объекта-задание
HANDLE hJ = OpenJobObject(JOB_OBJECT_ASSIGN_PROCESS,FALSE,str);

//в предыдущей строке 2-й параметр bInheritHandles - флаг наследования дескриптора...
//каково его назначение?

//Добавим процесс в задание
//AssignProcessToJobObject(hJ,???);



И вопрос в том, как получить дескриптор процесса, добавляемого в задание?
И ещё мне не понятно, как устанавливать ограничения для всех процессов в "задании" на класс приоритета?
(Знаю только константы приоритетов..как использовать, не пойму)..

Сообщение отредактировано: 18192123 -
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #2


Гость






Ну, у меня вот так отработало:
#define JOB_ID "MyFirstJob\0"
void __fastcall TForm1::Button1Click(TObject *Sender)
{
HANDLE hjob = CreateJobObject(NULL, JOB_ID);

STARTUPINFO si = { sizeof(si) };
PROCESS_INFORMATION pi;

CreateProcess(NULL, "notepad.exe", NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si,π);
AssignProcessToJobObject(hjob, pi.hProcess);
ResumeThread(pi.hThread);
CloseHandle(pi.hThread);

HANDLE h[2];
h[0] = pi.hProcess;
h[1] = hjob;
DWORD dw = WaitForMultipleObjects(2, h, FALSE, INFINITE);
switch (dw -WAIT_OBJECT_0) {
case 0:
// Процесс завершен
break;
case 1:
// Все время CPU, назначенное процессу, израсходовано
break;
}

CloseHandle(pi.hProcess);
CloseHandle(hjob);
}

(то же самое можно сделать и с несколькими процессами)... Вроде Job создается, в аттаче - картинка, как это видно через ProcessExplorer от SysInternals...

Сообщение отредактировано: volvo -


Эскизы прикрепленных изображений
Прикрепленное изображение
 К началу страницы 
+ Ответить 
сообщение
Сообщение #3


Профи
****

Группа: Пользователи
Сообщений: 920
Пол: Женский
Реальное имя: Марина

Репутация: -  2  +


Цитата(volvo @ 6.10.2008 21:44) *

#define JOB_ID "MyFirstJob\0"
void __fastcall TForm1::Button1Click(TObject *Sender)
{
//....
DWORD dw = WaitForMultipleObjects(2, h, FALSE, INFINITE);
switch (dw -WAIT_OBJECT_0) {
case 0:
// Процесс завершен
break;
case 1:
// Все время CPU, назначенное процессу, израсходовано
break;
}

}



Объясните пожалуйста, а для чего этот фрагмент нужен?

Сообщение отредактировано: 18192123 -
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #4


Гость






А что ты хочешь делать с запущенными тобой процессами? Ну, запустила ты процесс. Добавила в JobObject, что дальше? Сразу удалить? Или сделать задержку, чтобы посмотреть, что оно запустилось, и потом удалить? С помощью WaitForSingleObject я жду завершения запущенного процесса, и потом удаляю пакет...

Ну, а в switch-е просто диагностика, по какой причине процесс завершился...
 К началу страницы 
+ Ответить 
сообщение
Сообщение #5


Профи
****

Группа: Пользователи
Сообщений: 920
Пол: Женский
Реальное имя: Марина

Репутация: -  2  +


Попробовала переписать создание процесса и добавление его в "задание" на Visual C++...
Приложение запустилось, после нажатия на кнопку, в обработчике которой происходит создание процесса, приложение вылетело...(сообщение о произошедшем на прикреплённом рисунке)
Объясните пожалуйста, в чём я ошиблась?


...
HANDLE hjob = CreateJobObject(NULL, TEXT("LAB2"));

STARTUPINFO si = { sizeof(si) };
PROCESS_INFORMATION pi;

CreateProcess(NULL, TEXT("notepad.exe"), NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si,&pi); //здесь //и вылетает..
AssignProcessToJobObject(hjob, pi.hProcess);
ResumeThread(pi.hThread);
CloseHandle(pi.hThread);

HANDLE h[2];
h[0] = pi.hProcess;
h[1] = hjob;
DWORD dw = WaitForMultipleObjects(2, h, FALSE, INFINITE);
switch (dw -WAIT_OBJECT_0) {
case 0:
break;
case 1:
break;
}

CloseHandle(pi.hProcess);
CloseHandle(hjob);
...



Сообщение отредактировано: 18192123 -


Эскизы прикрепленных изображений
Прикрепленное изображение
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #6


Гость






Старая проблема... Вкратце: второй параметр функции CreateProcess должен быть типа LPCSTR, то есть, должен быть доступен как для чтения, так и для записи... Предыдущие версии (VC6 и ниже), да и Билдер (до 2007 включительно, в Билдере 2009 тоже начнутся проблемы) работают с CreateProcessA, которая хоть и получает константную строку, но в процессе работы конвертирует ее во внутренний юникодный буфер с помощью MultiByteToWideChar, и потом вызывает CreateProcessW, которая и создает процесс...

Когда же ты работаешь в VC2005+ (или Builder 2009), под вызовом CreateProcess подразумевается прямой вызов CreateProcessW, без промежуточных преобразований... Но ведь TEXT("notepad.exe") - это константа только для чтения, поэтому и возникает ошибка... Исправлять - так:

...
TCHAR lpProcName[]=TEXT("notepad.exe"); // создаем доступный для чтения _и записи_ буфер
CreateProcess(NULL, lpProcName, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, & si, & pi);
...
 К началу страницы 
+ Ответить 
сообщение
Сообщение #7


Профи
****

Группа: Пользователи
Сообщений: 920
Пол: Женский
Реальное имя: Марина

Репутация: -  2  +


Цитата(volvo @ 19.10.2008 19:34) *

... поэтому и возникает ошибка... Исправлять - так:

Большое спасибо!
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #8


Профи
****

Группа: Пользователи
Сообщений: 920
Пол: Женский
Реальное имя: Марина

Репутация: -  2  +


У меня такой вопрос: если я хочу создать несколько процессов (VC++ 2008 EE), мне нужно задействовать по нескольку структурных переменных типов STARTUPINFO и PROCESS_INFORMATION или это лишнее (с учётом того, что с созданными процессами нам потом работать - объединять в задание)?
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #9


Гость






Дублирование STARTUPINFO в любом случае лишнее... Попробовал в код из сообщения №2 добавить еще один процесс, не добавляя для него STARTUPINFO - процессы нормально добавляются (обрати внимание, в функции CreateProcess предпоследний параметр - IN, то есть, не возвращает ничего нового из функции, а вот последний - OUT, значит возвращает полезную информацию)...
 К началу страницы 
+ Ответить 
сообщение
Сообщение #10


Профи
****

Группа: Пользователи
Сообщений: 920
Пол: Женский
Реальное имя: Марина

Репутация: -  2  +


Вот что у меня получилось..
Вылетает с ошибкой Run-Time Check Failure #2 - Stack around the variable 'h' was corrupted.


RECT Rect;
GetClientRect(hwnd,&Rect);

TCHAR lpProcName[]=TEXT("");
TCHAR lpProcName1[]=TEXT("");
TCHAR lpProcName2[]=TEXT("");

HANDLE hjob = CreateJobObject(NULL, TEXT("LAB2"));

STARTUPINFO si = { sizeof(si) };
PROCESS_INFORMATION pi,pi1,pi2;

GetWindowText(hEditProc,(LPWSTR)lpProcName,30);
GetWindowText(hEditProc1,(LPWSTR)lpProcName1,30);
GetWindowText(hEditProc2,(LPWSTR)lpProcName2,30);
CreateProcess(NULL, lpProcName, NULL, NULL, FALSE,CREATE_SUSPENDED, NULL, NULL, & si, & pi);
CreateProcess(NULL, lpProcName1, NULL, NULL, FALSE,CREATE_SUSPENDED, NULL, NULL, & si, & pi1);
CreateProcess(NULL, lpProcName2, NULL, NULL, FALSE,CREATE_SUSPENDED, NULL, NULL, & si, & pi2);
AssignProcessToJobObject(hjob, pi.hProcess);
AssignProcessToJobObject(hjob, pi1.hProcess);
AssignProcessToJobObject(hjob, pi2.hProcess);
ResumeThread(pi.hThread);
ResumeThread(pi1.hThread);
ResumeThread(pi2.hThread);
CloseHandle(pi.hThread);
CloseHandle(pi1.hThread);
CloseHandle(pi2.hThread);

HANDLE h[3];
h[0] = pi.hProcess;
h[1] = pi1.hProcess;
h[2] = pi2.hProcess;
h[3] = hjob;
DWORD dw = WaitForMultipleObjects(3, h, FALSE, INFINITE);
switch (dw -WAIT_OBJECT_0) {
case 0:
//EdProc->Text="Процесс завершен"/;
break;
case 1:
//EdProc->Text="Все время CPU, назначенное процессу, израсходовано";
break;
}

CloseHandle(pi.hProcess);
CloseHandle(pi1.hProcess);
CloseHandle(pi2.hProcess);
CloseHandle(hjob);
....



Объясните пожалуйста, что я не правильно делаю?

Сообщение отредактировано: 18192123 -
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #11


Гость






Цитата
что я не правильно делаю?
Портишь стэк:

	HANDLE h[4];
h[0] = pi.hProcess;
h[1] = pi1.hProcess;
h[2] = pi2.hProcess;
h[3] = hjob;
DWORD dw = WaitForMultipleObjects(4, h, FALSE, INFINITE);

должно работать...
 К началу страницы 
+ Ответить 
сообщение
Сообщение #12


Профи
****

Группа: Пользователи
Сообщений: 920
Пол: Женский
Реальное имя: Марина

Репутация: -  2  +


Цитата(volvo @ 21.10.2008 22:51) *

должно работать...

Получилось!) Спасибо!!
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #13


Профи
****

Группа: Пользователи
Сообщений: 920
Пол: Женский
Реальное имя: Марина

Репутация: -  2  +


Хочу установить ограничения для всех процессов в созданном ранее задании на класс приоритета...Скажите пожалуйста, а какие это классы? И устанавливать нужно, используя функцию SetInformationJobObject() или нет?
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #14


Гость






Цитата
устанавливать нужно, используя функцию SetInformationJobObject()
Да, ограничения на Job устанавливаются через SetInformationJobObject()

Цитата
Хочу установить ограничения для всех процессов в созданном ранее задании на класс приоритета...
Ну, так в чем проблема? smile.gif

    // создаем объект ядра "задание"
HANDLE hjob = CreateJobObject(NULL, NULL);

// вводим ограничения для процессов в задании
// сначала определяем некоторые базовые ограничения
JOBOBJECT_BASIC_LIMIT_INFORMATION jobli = { 0 };

// процесс всегда выполняется с классом приоритета idle
jobli.PriorityClass = IDLE_PRIORITY_CLASS;

// задание не может использовать более одной секунды процессорного времени
jobli.PerJobUserTimeLimit.QuadPart = 10000000;

// 1 секунда, выраженная в 100-наносекундных интервалах
// два ограничения, которые я налагаю на задание (процесс)
jobli.LimitFlags = JOB_OBJECT_LIMIT_PRIORITY_CLASS | JOB_OBJECT_LIMIT_JOB_TIME;

SetInformationJobObject(hjob, JobObjectBasicLimitInformation, &jobli, sizeof(jobli));

// теперь вводим некоторые ограничения по пользовательскому интерфейсу
JOBOBJECT_BASIC_UI_RESTRICTIONS jobuir;
jobuir.UIRestrictionsClass = JOB_OBJECT_UILIMIT_NONE;

// процесс не имеет права останавливать систему
jobuir.UIRestrictionsClass |= JOB_OBJECT_UILIMIT_EXITWINDOWS;

// процесс не имеет права обращаться к USER-объектам в системе
// (например, к другим окнам)
jobuir.UIRestrictionsClass |= JOB_OBJECT_UILIMIT_HANDLES;

SetInformationJobObject(hjob, JobObjectBasicUIRestrictions,
&jobuir, sizeof(jobuir));

// Порождаем процесс, который будет размещен в задании.

// Ну, дальше ты знаешь, что делать...
(фрагмент программы - из книги Дж. Рихтера "Создание эффективных Win32 приложений", глава 5)
 К началу страницы 
+ Ответить 
сообщение
Сообщение #15


Профи
****

Группа: Пользователи
Сообщений: 920
Пол: Женский
Реальное имя: Марина

Репутация: -  2  +


Спасибо большое!)


TCHAR lpProcName[256]=TEXT("");

GetWindowText(hEditPriority,(LPWSTR)lpProcName,50);
if (lpProcName==TEXT("IDLE"))
jobli.PriorityClass = IDLE_PRIORITY_CLASS;
if (lpProcName==TEXT("NORMAL"))
jobli.PriorityClass = NORMAL_PRIORITY_CLASS;
if (lpProcName==TEXT("BELOW_NORMAL"))
jobli.PriorityClass = BELOW_NORMAL_PRIORITY_CLASS;
if (lpProcName==TEXT("ABOVE_NORMAL"))
jobli.PriorityClass = ABOVE_NORMAL_PRIORITY_CLASS;




Проблема в том, что ни в одно условие не заходит..соответственно jobli.PriorityClass в конце концов остаётся 0..
Хотя при трассировке получаю такое..(прикреплённый рисунок)
Скажите пожалуйста, В чём может быть причина?


Эскизы прикрепленных изображений
Прикрепленное изображение
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #16


Гость






Цитата
В чём может быть причина?
Ай-яй-яй... Нельзя строки сравнивать через "=="... Надо пользоваться функциями сравнения... Ну, скажем:

	if(!wcscmp(lpProcName, L"IDLE")) {
jobli.PriorityClass = IDLE_PRIORITY_CLASS;
}
В Билдере по-крайней мере работает...
 К началу страницы 
+ Ответить 
сообщение
Сообщение #17


Профи
****

Группа: Пользователи
Сообщений: 920
Пол: Женский
Реальное имя: Марина

Репутация: -  2  +


Цитата(volvo @ 24.10.2008 1:39) *

Ай-яй-яй... Нельзя строки сравнивать через "=="... Надо пользоваться функциями сравнения...

Ойййййй...Ну всё) Верный признак того, что пора спать)
Спасибо большое!!!!!
 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #18


Профи
****

Группа: Пользователи
Сообщений: 920
Пол: Женский
Реальное имя: Марина

Репутация: -  2  +


Теперь пытаюсь вывести информацию о имеющемся задании...
Вот такая ошибка:
1>c:\study\3 kyrs\os\lab3\lab3\main.cpp(301) : error C2440: 'initializing' : cannot convert from 'void *' to 'PJOBOBJECT_BASIC_ACCOUNTING_INFORMATION'
Объясните пожалуйста, как устранить эту ошибку?

//...

wchar_t pszStrPID[256];

DWORD size = sizeof(JOBOBJECT_BASIC_ACCOUNTING_INFORMATION);
PJOBOBJECT_BASIC_ACCOUNTING_INFORMATION pjbai= _alloca(size); //(301)
QueryInformationJobObject(hjob,JobObjectBasicAccountingInformation,pjbai,size,&size);

HWND hActivePr=CreateWindow(TEXT("STATIC"),NULL,WS_CHILD|WS_VISIBLE|SS_LEFT,
(int)(Rect.left+135),(int)(Rect.top+120),(int)(Rect.right- Rect.left-700),20,hwnd,NULL,hInstance,NULL);
wsprintf(pszStrPID,_T("%d"), pjbai->ActiveProcesses);
SendMessage(hActivePr,WM_SETTEXT, 0, (LPARAM)(LPCSTR)pszStrPID);

 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 
сообщение
Сообщение #19


Гость






Цитата
как устранить эту ошибку?
Как и всегда при выделении памяти - явным приведением типов (практически все функции, выделяющие память, возвращают универсальный void*, а ты на выходе его ловишь, и превращаешь в то, что нужно):
PJOBOBJECT_BASIC_ACCOUNTING_INFORMATION pjbai =
(PJOBOBJECT_BASIC_ACCOUNTING_INFORMATION)_alloca(size);
(Обрати внимание на предупреждение, что _alloca() не рекомендавана к использованию; есть более безопасная версия: _malloca()...)
 К началу страницы 
+ Ответить 
сообщение
Сообщение #20


Профи
****

Группа: Пользователи
Сообщений: 920
Пол: Женский
Реальное имя: Марина

Репутация: -  2  +


Ранее я устанавливала приоритет..:

JOBOBJECT_BASIC_LIMIT_INFORMATION jobli = { 0 };

// процесс всегда выполняется с классом приоритета ...
GetWindowText(hEditPriority,(LPWSTR)lpProcName,50);
if(!wcscmp(lpProcName, L"IDLE"))
{
jobli.PriorityClass = IDLE_PRIORITY_CLASS;
MessageBox(hWndMain,TEXT("IDLE"),TEXT("Class of Priority:"),MB_ICONINFORMATION);
}
if(!wcscmp(lpProcName, L"NORMAL"))
{
jobli.PriorityClass = NORMAL_PRIORITY_CLASS;
MessageBox(hWndMain,TEXT("NORMAL"),TEXT("Class of Priority:"),MB_ICONINFORMATION);
}
if(!wcscmp(lpProcName, L"BELOW_NORMAL"))
{
jobli.PriorityClass = BELOW_NORMAL_PRIORITY_CLASS;
MessageBox(hWndMain,TEXT("BELOW_NORMAL"),TEXT("Class of Priority:"),MB_ICONINFORMATION);
}
if(!wcscmp(lpProcName, L"ABOVE_NORMAL"))
{
jobli.PriorityClass = ABOVE_NORMAL_PRIORITY_CLASS;
MessageBox(hWndMain,TEXT("ABOVE_NORMAL"),TEXT("Class of Priority:"),MB_ICONINFORMATION);
}



Когда выводила информацию о задании, наткнулась на то, что класс приоритета всегда остаётся NORMAL(32)...
И вот теперь не пойму...где ошиблась..или в чём причина? Объясните пожалуйста.

size = sizeof(JOBOBJECT_BASIC_LIMIT_INFORMATION);
PJOBOBJECT_BASIC_LIMIT_INFORMATION pjbli=(PJOBOBJECT_BASIC_LIMIT_INFORMATION)_malloca(size);
QueryInformationJobObject(hjob,JobObjectBasicLimitInformation,pjbli,size,&size);
HWND hPriority=CreateWindow(TEXT("STATIC"),NULL,WS_CHILD|WS_VISIBLE|SS_LEFT,
(int)(Rect.left+500),(int)(Rect.top+120),(int)(Rect.right- Rect.left-700),20,hwnd,NULL,hInstance,NULL);
wsprintf(pszStrPID,_T("%d"), pjbli->PriorityClass);
SendMessage(hPriority,WM_SETTEXT, 0, (LPARAM)(LPCSTR)pszStrPID);

 Оффлайн  Профиль  PM 
 К началу страницы 
+ Ответить 

2 страниц V  1 2 >
 Ответить  Открыть новую тему 
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 





- Текстовая версия 24.10.2021 1:34
500Gb HDD, 6Gb RAM, 2 Cores, 7 EUR в месяц — такие хостинги правда бывают
Связь с администрацией: bu_gen в домене octagram.name