Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ОС Laba1 Саттаров РР.doc
Скачиваний:
5
Добавлен:
29.07.2019
Размер:
86.53 Кб
Скачать

Параметры psaProcess, psaThread и blnheritHandles

Параметры psaProcess и psaThread позволяют определить нужные атрибуты защиты для объектов «процесс» и «поток» соответственно. В эти параметры можно занести NULL, и система закрепит за данными объектами дескрипторы защиты по умолчанию.

  1. Каким образом родительский процесс может управлять дочерним?

Когда поток в приложении вызывает CreateProcess, система создает объект ядра «процесс» и «поток» соответственно. В эти параметры можно занести NULL, и система закрепит за данными объектами дескрипторы защиты по умолчанию.

  1. Что наследуется дочерним процессом от родительского?

Если родительский процесс создает блок переменных окружения и хочет передать его дочернему процессу, тот не наследует текущие каталоги родительского процесса автоматически. Вместо этого у дочернего процесса текущими на всех дисках становятся корневые каталоги. Чтобы дочерний процесс унаследовал текущие каталоги родительского, последний должен создать соответствующие переменные окружения (и сделать это до порождения другого процесса). Родительский процесс может узнать, какие каталоги являются текущими, вызвав GetFullPathName:

DWORD GetFullPathName( PCTSTR pszFile, DWORD cchPath, PTSTR pszPath, PTSTR *ppszFilePart);

Например, чтобы получить текущий каталог на диске С: функцию вызывают так:

TCHAR szCurDir[MAX_PATH];

GetFullPathName(TEXT("C:"), MAX_PATH, szCurDir, NULL);

Дочерний процесс может унаследовать описатели объектов ядра от родительского процесса.

  1. Каким образом можно отследить, когда дочерний процесс завершил работу?

Родительский процесс, вызвав функцию GetExitCodeProcess, может проверигь, завершен ли процесс, идентифицируемый параметром hProcess, и, если да, определить код завершения:

BOOL GetExitCodeProcess( HANDLE hProcess, PDWORD pdwExitCode);

Код завершения возвращается как значение типа DWORD, на которое указывает pdwExitCode. Если на момент вызова GetExitCodeProcess процесс еще не завершился, в DWORD заносится идентификатор STILL_ACTIVE (определенный как 0x103) А если он уничтожен, функция возвращает реальный код его завершения.

В принципе можно написать код, который, периодически вызывая функцию GetExitCodeProcess и проверяя возвращаемое ею значение, определял бы момент завершения процесса. В принципе такой код мог бы сработать во многих ситуациях, но он был бы неэффективен.

  1. Как запустить обособленный дочерний процесс?

Все же чаще приложение все-таки создает другие процессы как обособленные (detached processes) Это значит, что после создания и запуска нового процесса родительскому процессу нет нужды с ним взаимодействовать или ждать, пока тот закончит работу Именно так и действует Explorer: запускает для пользователя новые процессы, а дальше его уже не волнует, что там с ними происходит.

Чтобы обрубить все пуповины, связывающие Explorer c дочерним процессом, ему нужно (вызовом CloseHandle) закрыть свои описатели, связанные с новым процессом и его первичным потоком.

Приведенный ниже фрагмент кода демонстрирует, как, создав процесс, сделать его обособленным

PROCESS_INFORMATION pi;

// Порождение дочернего процесса.

BOOL fSuccess = CreateProcess(..., &pi);

if (fSuccess) {

   // Разрешаем системе уничтожить объекты ядра поток и процесс дочернего //процесса сразу по его завершении

   CloseHandle(pi.hThread);

   CloseHandle(pi.hProcess);

}

Листинги программ

Файл stdafx.h

#include <iostream>

#include <tchar.h>

#include <windows.h>

#include <stdio.h>

#include < conio.h>

Файл labOC1.cpp

// LabOC1.cpp : Defines the entry point for the console application.

//

#include "stdafx.h"

int _tmain(int argc, _TCHAR* argv[])

{

DWORD dwExitCode;

char buf[200];

printf("test");

GetCurrentDirectory(200,buf);

printf("\n%s\n",buf);

SetCurrentDirectory("C:\\work");

GetCurrentDirectory(200,buf);

printf("\n%s\n",buf);

GetEnvironmentVariable("OS", buf, 200);

printf("\n%s\n",buf);

GetEnvironmentVariable("TEMP", buf, 200);

printf("\n%s\n",buf);

GetEnvironmentVariable("COMSPEC", buf, 200);

printf("\n%s\n",buf);

GetEnvironmentVariable("NUMBER_OF_PROCESSORS", buf, 200);

printf("\n%s\n",buf);

SetEnvironmentVariable("OS", "Linux");

GetEnvironmentVariable("OS", buf, 200);

printf("\n%s\n",buf);

STARTUPINFO si2 = { sizeof(si2) };

PROCESS_INFORMATION pi2;

SECURITY_ATTRIBUTES saProcess, saThread;

PROCESS_INFORMATION piProcessB, piProcessC;

TCHAR szPath[MAX_PATH];

saProcess.nLength = sizeof(saProcess);

saProcess.lpSecurityDescriptor = NULL;

saProcess.bInheritHandle = TRUE;

// Дескриптор идентифицирует новый поток

// объект должен быть не наследуемым.

saThread.nLength = sizeof(saThread);

saThread.lpSecurityDescriptor = NULL;

saThread.bInheritHandle = FALSE;

CreateProcess(NULL, TEXT("NOTEPAD"), &saProcess, &saThread, FALSE, 0, NULL, NULL, &si2, &pi2);

TCHAR szCommandLine[] = TEXT("C:\\work\\4303\\Child\\Debug\\Child.exe 1 2 3 4 56");

wsprintf (buf,"%d",pi2.hProcess);

SetEnvironmentVariable("descr",buf);

STARTUPINFO si = { sizeof(si) };

PROCESS_INFORMATION pi;

CreateProcess(NULL, szCommandLine, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi);

WaitForSingleObject(pi.hProcess, INFINITE);

// Дочерний процесс завершен; получаем его код завершения.

GetExitCodeProcess(pi.hProcess, &dwExitCode);

printf("\n%d\n",dwExitCode);

getch();

return 0;

}