Управление процессами
| Категория реферата: Рефераты по информатике, программированию
| Теги реферата: реферат орган, диплом
| Добавил(а) на сайт: Вонифатий.
Предыдущая страница реферата | 1 2 3 4 5 6 7 8 9 | Следующая страница реферата
switch(WSTOPSIG(status)){ /*анализируем код сигнала, по которому произошла остановка */
case SIGINT: printf("INT n"); break;/* выводим причину остановки */
case SIGTRAP: . . . . . . break;
.
.
.
default: printf("%d", WSTOPSIG(status));
}
if (WSTOPSIG(status)!=SIGTRAP) exit(1); /* Если процесс остановился не по SIGTRAP тогда выходим */
if (WIFEXITED(status)){ /* проверяем случай, если процесс завершился нормально */
printf("Процесс завершился, код завершения = %d n", WEXITSTATUS(status));
exit(0);
}
ptrace(PT_CONTINUE, pid, (caddr_t) 1, 0); /* Если был SIGTRAP, продолжаем процесс */
} /* End for(;;) */
exit(0);
}
Мы обработали ситуацию остановки и ситуацию нормального завершения процесса. При первой итерации цикла, мы остановимся и дождемся первого сигнала SIGTRAP. По этому сигналу мы выведем нужную нам информацию. Затем, проверим, не закончился ли наш процесс нормально, и т.к. он не может закончиться нормально (он выполняет деление на ноль), то мы обратимся к функции ptrace, которая продолжит процесс с прерванного места. Мы снова попадем на wait. Здесь мы дождемся события, связанного с делением на ноль, и обработаем это событие. В итоге, на стандартный вывод попадут две порции данных: первая - вывод точки прерывания, вершины стека и сигнала для начальной ситуации, и второе - мы получим блок той же информации и код сигнала FPI (Float Point Interrupt) на делении на ноль.
Рекомендуется разобрать этот пример и адаптировать для ваших машин на практикуме.
Лекция №16
Нелокальные переходы
На этой лекции мы с вами обсудим некоторые дополнительные возможности по организации управления ходом процесса в UNIX. Возникает необходимость предоставления в процессе возможности перезапуска в процессе каких-то его веток при возникновении некоторых ситуаций.
Предположим, у нас есть процесс, который занимается обработкой достаточно больших наборов данных, и мы хотим написать процесс, который будет работать следующим образом. В начальный момент времени наш процесс получает некоторый набор данных, и начинает каким-то образом выполнять вычисления. Известно, что при некоторых наборах данных, возможно возникновение внештатных ситуаций, например, переполнение или деление на ноль. Мы бы хотели написать программу, которая обрабатывала бы внештатную ситуацию, и после обработки ее переходила бы снова в начальную точку процесса, загружала бы новые наборы данных и начинала работу с ними.
Для решения такой задачи, мы должны уметь обрабатывать сигналы, возникающие в процессе. Это можно сделать с помощью функции signal и ее возможностей. Кроме того, нам бы хотелось возвращаться в некоторые помеченные в программе точки, не через последовательность входов и выходов из функции, а с помощью безусловного перехода (как бы goto N), потому что механизм обработки сигналов не позволит корректно работать с такой задачей. Можно в принципе написать функцию обработки сигнала, которая при возникновении одного из сигналов делает повторный вызов всей программы. Но это не совсем корректно, т.к. при вызове функции-обработчика сигнала фиксируется состояние стека, и в общем случае система ожидает выхода из функции обработчика через return (при этом система возвращает нас в прерванное место и освобождает стек). Если не будет произведен выход через return, в стеке будет накапливаться ненужная информация, и все это приведет к деградации системы.
Для решения таких задач имеются т.н. нелокальные переходы. Достигаются они с использованием двух функций, которые продекларированы в setjmp.h и имеют следующий интерфейс:
int setjmp(jmp_buf env);
int longjmp(jmp_buf env, int val);
Функция setjmp фиксирует точку обращения к этой функции, т.е. в структуре данных, связанной с переменной env сохраняется текущее состояние процесса (все атрибуты и в т.ч. состояние стека) в точке обращения к setjmp. При обращении к этой функции здесь, setjmp возвращает нулевое значение.
При обращении к функции longjmp(env, val) происходит передача управления на точку, атрибуты которой зафиксированы в структуре env, т.е. в то место, где было обращение к setjmp(env). При этом, после этого перехода setjmp вернет значение val.
Рассмотрим маленький пример.
# include
jmp_buf save;
void main(void)
{ int ret;
switch(ret=setjmp(save)){ /* при первой проверке ret будет равно нулю */
case 0: printf("....."); /* этот printf выведет некоторую строку */
a(); /* вызов функции a() */
printf("....."); /* этот printf не сработает никогда */
default: break;
}
}
void a(void)
{ longjmp(save, 1); /* длинный переход на setjmp, ret будет равно 1 */
}
Нелокальный переход - это несколько некорректная возможность операционной системы, потому что нехорошо входить в блочные структуры не через начало и выходить не через конец. Здесь все нарушается. Однако для некоторых ситуаций эти возможности бывают полезны. В частности эти функции могут быть использованы для передачи управления из функции-обработчика сигнала в некоторую точку программы.
Длинный переход корректно работает со стеком. При входе в точку, установленную с помощью setjmp, он восстанавливает все то состояние (в том числе и состояние стека), которое было при установке этой точки. Надо заметить, что longjmp восстанавливает не сам стек, а лишь указатель стека.
Работа со стеком всегда должна удовлетворять правилу: перед обращением к функции и после возврата из нее, уровень стека должен быть одинаковым. Если уровень станет больше или меньше, это гарантировано приведет к проблемам, потому что рано или поздно стек либо переполнится, либо программа полезет за нижний его уровень, что тоже плохо.
Вопрос: предположим мы установили setjmp в некоторой функции, мы вернулись из этой функции, и затем выполнили переход longjmp (т.е. вошли в функцию не сначала). Куда при выходе из этой функции произойдет возврат, потому что в общем случае содержимое стекового кадра этой функции будет случайным (т.к. в буфере env содержится указатель стека, а не сам стек)? Возврат произойдет корректно, т.к. в буфере env адрес возврата будет сохранен, а вот значения автоматических и регистровых переменных этой функции действительно окажется случайным, потому что стек в буфере не сохраняется. Но это есть правила игры. Т.е. здесь на решение программиста налагается ответственность.
Рекомендуем скачать другие рефераты по теме: сочинения по литературе, реферат на тему государство.
Категории:
Предыдущая страница реферата | 1 2 3 4 5 6 7 8 9 | Следующая страница реферата