Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
SP.docx
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
29 Кб
Скачать
☆

19) Наследование дескрипторов

Большинство объектов категории Kernel могут быть наследуемыми или ненаследуемыми. Свойство наследования объекта означает, что если наследуемый объект создан или открыт в некотором процессе, то к этому объекту будут также иметь доступ все процессы, которые создаются этим процессом, т. е. являются его потомками. Свойство наследования объекта определяется его дескриптором, который также может быть наследуемым или ненаследуемым. Для того чтобы объект стал наследуемым, необходимо сделать наследуемым его дескриптор и наоборот.

Свойство наследования не поддерживается для объектов, использование которых несколькими процессами нарушило бы изолированность памяти процесса от других процессов. Поэтому не могут наследоваться следующие дескрипторы:

□ дескриптор виртуальной памяти, который возвращает любая из функций

LocalAlloc, GlobalAlloc, HeapCreate ИЛИ HeapAlloc;

□ дескриптор динамической библиотеки, который возвращает функция

LoadLibrary.

! Листинг 4.8. Завершение потока в родительском процессе, используя | дескриптор потока, который передается через командную строку

# include <windows.h>

#include <conio.h>

int main(int argc, char *argv[])

{

HANDLE hThread; char с;

// преобразуем символьное представление дескриптора в число

hThread = (HANDLE)atoi (argv[l] ) ;

// ждем команды о завершении потока while (true)

{

_cputs("Input 1t1 to terminate the thread: "); с = _getch(); if (c == 't1)

25). Аппаратная реализация синхронизации

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

Инструкция "проверить и установить"

В наборе инструкций процессора Motorola 68000 существует инструкция tas (test and set), которая имеет следующую реализацию:

int tas(int& target)

int temp;

temp = target; target = 1; return temp;}

Инструкция "обменять содержимое переменных"

В наборе инструкций процессоров семейства Intel х86 существует инструкция xchg (exchange), которая имеет следующую реализацию:

void xchg(register int r, int x){

int temp;

temp = r; r = x; x = temp;}

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

int lock =0; // переменная, которая запирает вход в критическую

// секцию

void thread(){

while(true){

register int key; // ключ к замку

key = 1;

while(key == 1) // ждать, пока замок закрыт

xchg(key, lock);

critical section(); // критическая секция

lock = 0; // открыть замок

non_critical_section(); // остальной код}}

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]