Читаем Системное программирование в среде Windows полностью

По завершении выполнения функции указатель lphTargetHandle будет указывать на копию исходного дескриптора, hSourceHandle. hSourceHandle является дескриптором дублируемого объекта в процессе, указанном дескриптором hSourceProcessHandle, и должен иметь права доступа PROCESS_DUP_HANDLE; если указанного дескриптора в исходном процессе не существует, функция DuplicateHandle завершается ошибкой. Новый дескриптор, на который указывает указатель lphTargetHandle, является действительным в целевом процессе, hTargetProcessHandle. Обратите внимание на то, что в нашем рассмотрении фигурировали три процесса, включая вызывающий. Часто в роли вызывающего процесса выступает целевой или исходный процесс, и тогда соответствующий дескриптор получают с помощью функции GetCurrentProcess. Заметьте также, что процесс может создать дескриптор в другом процессе; если вы это делаете, то вам потребуется механизм, с помощью которого можно было бы передать в другой процесс идентификационные данные нового дескриптора.

Функция DuplicateHandle может применяться к дескрипторам любого типа.

Если действие параметра dwDesiredAccess не отменяется флагом DUPLICATE_SAME_ACCESS параметра dwOptions, то у него может быть много возможных значений (для получения более подробных сведений обратитесь к библиотеке MSDN оперативного справочного руководства).

Параметр dwOptions может содержать любую комбинацию указанных ниже двух флагов.

• DUPLICATE_CLOSE_SOURCE — вызывает закрытие исходного дескриптора.

• DUPLICATE_SAME_ACCESS — вынуждает игнорировать параметр dwDesiredAccess. 

Напоминание

Ядро Windows поддерживает счетчики ссылок для всех объектов; этот счетчик представляет количество различных дескрипторов, ссылающихся на данный объект. В то же время, приложения не имеют доступа к этому счетчику. Любой объект не может быть уничтожен до тех пор, пока не будет закрыт его последний дескриптор, а счетчик ссылок не примет нулевое значение. Унаследованные и продублированные дескрипторы считаются отличными от исходных и также учитываются в счетчике ссылок. Наследуемые дескрипторы используются в программе 6.1 далее в этой главе. В то же время, дескрипторы, переданные из одного процесса в другой посредством той или иной формы механизма IPC, не считаются независимыми, и поэтому если один процесс закрывает такой дескриптор, то другие процессы использовать его не могут. Подобной методикой пользуются редко, однако в упражнении 6.2 вам предлагается передать значение унаследованного дескриптора из одного процесса в другой, используя механизм IPC.

Далее вы узнаете о том, как определить, завершено ли выполнение процесса.

<p>Завершение и прекращение выполнения процесса</p>

После того как процесс завершил свою работу, он, или, точнее, выполняющийся в этом процессе поток, может вызвать функцию ExitProcess, указав в качестве параметра кодом завершения (exit code):

VOID ExitProcess(UINT uExitCode) 

Эта функция не осуществляет возврата. Вместо этого она завершает вызывающий процесс и все его потоки. Обработчики завершения игнорируются, но делаются все необходимые вызовы точек входа DllMain (см. главу 5) с кодом отключения от библиотеки. Код завершения связывается с процессом. Выполнение оператора return в основной программе с использованием кода возврата равносильно вызову функции ExitProcess, в котором этот код возврата указан в качестве кода завершения.

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

BOOL GetExitCodeProcess(HANDLE hProcess, LPDWORD lpExitCode) 

Процесс, идентифицируемый дескриптором hProcess, должен обладать правами доступа PROCESS_QUERY_INFORMATION (см. описание функции OpenProcess, которая нами уже обсуждалась). lpExitCode указывает на переменную типа DWORD, которая принимает значение кода завершения. Одним из ее возможных значений является STILL_ACTIVE, означающее, что данный процесс еще не завершился. 

Перейти на страницу:

Похожие книги

C++: базовый курс
C++: базовый курс

В этой книге описаны все основные средства языка С++ - от элементарных понятий до супервозможностей. После рассмотрения основ программирования на C++ (переменных, операторов, инструкций управления, функций, классов и объектов) читатель освоит такие более сложные средства языка, как механизм обработки исключительных ситуаций (исключений), шаблоны, пространства имен, динамическая идентификация типов, стандартная библиотека шаблонов (STL), а также познакомится с расширенным набором ключевых слов, используемым в .NET-программировании. Автор справочника - общепризнанный авторитет в области программирования на языках C и C++, Java и C# - включил в текст своей книги и советы программистам, которые позволят повысить эффективность их работы. Книга рассчитана на широкий круг читателей, желающих изучить язык программирования С++.

Герберт Шилдт

Программирование, программы, базы данных
Programming with POSIX® Threads
Programming with POSIX® Threads

With this practical book, you will attain a solid understanding of threads and will discover how to put this powerful mode of programming to work in real-world applications. The primary advantage of threaded programming is that it enables your applications to accomplish more than one task at the same time by using the number-crunching power of multiprocessor parallelism and by automatically exploiting I/O concurrency in your code, even on a single processor machine. The result: applications that are faster, more responsive to users, and often easier to maintain. Threaded programming is particularly well suited to network programming where it helps alleviate the bottleneck of slow network I/O. This book offers an in-depth description of the IEEE operating system interface standard, POSIX (Portable Operating System Interface) threads, commonly called Pthreads. Written for experienced C programmers, but assuming no previous knowledge of threads, the book explains basic concepts such as asynchronous programming, the lifecycle of a thread, and synchronization. You then move to more advanced topics such as attributes objects, thread-specific data, and realtime scheduling. An entire chapter is devoted to "real code," with a look at barriers, read/write locks, the work queue manager, and how to utilize existing libraries. In addition, the book tackles one of the thorniest problems faced by thread programmers-debugging-with valuable suggestions on how to avoid code errors and performance problems from the outset. Numerous annotated examples are used to illustrate real-world concepts. A Pthreads mini-reference and a look at future standardization are also included.

David Butenhof

Программирование, программы, базы данных