2010-12-16 4 views
4

Я выясняя, как сигналы работают в С. Вот один из примеров, взятых из старых экзаменов:Обработка сигналов в C

#include<signal.h> 
#include<unistd.h> 
#include<stdio.h> 
#include<errno.h> 

//#include <sys/types.h> 

void handler1(int sig) { 
printf("Phantom"); 
exit(0); 
} 
int main() 
{ 
    pid_t pid1; 
    signal(SIGUSR1, handler1); //installing signal handler 
    if((pid1 = fork()) == 0) { //forking 
     printf("Ghost"); 
     exit(0); 
    } 
    kill(pid1, SIGUSR1); 
    printf("Ninja"); 
    return 0; 
} 

До сих пор, GCC дает мне два ответа Ghost Ninja & Ninja Phantom. Может ли он произвести Ghost Phantom Ninja или любую другую комбинацию из 3 имен?

Один из способов я вижу, что может производить 3 имен: Вилок, бегите в ребенке, печать Ghost, выход (0) => в Parent, принимать/сигнал процесса и от обработчика сигналу печати Phantom, убить ребенок, печать Ninja. Но я не уверен, поддерживает ли моя «теория».

Также будет kill(pid1, SIGUSR1) invoke handler()?

Спасибо!

+0

Не ответ на вопрос как таковой, но вы должны ** никогда ** не вызывать printf() в обработчике сигналов. – JeremyP 2010-12-16 11:05:23

ответ

5

Давайте рассмотрим эту линейную линию. Настройте обработчик сигнала, затем вилку. Ребенок печатает «Призрак» и выходит. Родитель заставляет ребенка печатать «Phantom» и выйти. Затем родитель печатает «ниндзя».

Итак, у вас действительно есть состояние гонки. Если родитель запускает его SIGUSR1 перед ребенком гравюр «Призрак», то вы получите Phantom Ninja, или, возможно, Ninja Phantom (действительно убивает блок?)

Но, если вы не можете получить сигнал от времени, то вы Получите Ghost Ninja, когда ребенок закончит перед родительскими сигналами. Я не думаю, что обратное возможно.

Теперь можно предположить, что сигнал может быть точно вовремя ударить между printf и exit, в этом случае Ghost бы закончить, а затем Phantom затем Ninja - снова или наоборот, я думаю.

Это действительно тонкий и чувствительный к времени ОС.

@Everyone - не проверено! Не стесняйтесь противоречить мне, но мне будет интересно узнать, почему в качестве ОП.

+0

«Но если вы не можете получить сигнал вовремя, тогда вы получите Ghost Ninja, когда ребенок закончит перед родительскими сигналами. Я не думаю, что обратное возможно». Если ребенок выйдет, родитель продолжит убивать или он сначала примет сигнал от обработчика ??? – newprint 2010-12-16 09:12:15

1

Позволяет отмечать линии с номерами строк первой следующим образом:

signal(SIGUSR1, handler1); //installing signal handler ---- 1 
    if((pid1 = fork()) == 0) { //forking    ---- 2 
     printf("Ghost");        ---- 3 
     exit(0);          ---- 4 
} 
    kill(pid1, SIGUSR1);        ---- 5 
    printf("Ninja");         ---- 6 

Теперь с выше коде, если Ребенок выполняет первый и если 3 выполняется первым, а затем ребенок приостанавливается и родителей начинается Выполняется с 5. Это напечатает GhostPhantomNinja

Однако определенный порядок не может быть определен.

0

Здесь у вас есть два недетерминированных фактора, которые оба зависят от ОС: когда произойдет переключение контекста и когда придет сигнал.

Поскольку вы не можете управлять ими, я бы ответил, что любой заказ возможен. Попробуйте вставить wait() между командой и посмотрите, получите ли вы желаемые результаты.

0
//#include <sys/types.h> 
#include<stdlib.h> 
void handler1(int sig) { 
printf("Phantom\n"); 
waitpid(-1,NULL,0); 
//sexit(0); 
} 
int main() 
{ 
    pid_t pid1; 
    signal(SIGUSR1, handler1); //installing signal handler 
     printf("my pid is %d ha ha parent..\n",getpid()); 
    //if((pid1 = fork()) == 0) { //forking 
     pid1=fork(); 
     if(pid1==0)//in childe processs 
     { 
    printf("my pid is %d ha ha child..\n",getpid()); 
     printf("Ghost\n"); 
     sleep(6); 
     exit(0); 
    } 
    else{ 
    //sleep(4); 
    kill(pid1, SIGUSR1); 
    sleep(3); 
    printf("Ninja\n"); 
    return 0; 
} 
} 
+0

попробуйте это из-за сна. Как я использовал, тогда понимаю, как работает os, я имею в виду, как работает планировщик. – 2010-12-16 12:44:31

Смежные вопросы