русский
Germany.ruForen → Архив Досок→ Programmierung

Проблема с Signal-Handlerами

132  
genocidee посетитель20.10.06 16:48
genocidee
NEW 20.10.06 16:48 
Привет
Я пишу прогу на С под Линукс и у следующая проблема - я хочу изменить выполнение программы по какому-нибуть событию (передаеться через сигнал) таким образом чтоб сама программа *СРАЗУ* прервалась и выполнила нужную функцыю. Вопрос: как это реализовать? Проблема состоит в том что выполнение долгих функцый (таких как speep(X)) в *САМОМ* signal-handlere не допустимо.
пример программы:
void my_signalhandler(int s)
{
KEEP_RUNNUNG=0;
}
...
while( KEEP_RUNNING ){ /* main loop */
do_something(); /* функция блокируется на
... неопределенное время */
}
do_when_signal_comes(); /* должно быть запущено по сигналу и
требует длительного времени выполнения*/ ...
В этом примере проблема состоит в том что выполнение программы прерывается не после сигнала (и вызова handlera), а только после проверки KEEP_RUNNING в главном цыкле. Существуют ли какие либо методы асинхронного прерывания программы?
Или может ктонибуть посоветоваеть что нибуть еще,
Всем заранее благодарен!
Is this the real world, Neo?
#1 
  Chipolino знакомое лицо21.10.06 21:49
NEW 21.10.06 21:49 
in Antwort genocidee 20.10.06 16:48
Может я тебя неправильно понял , но цикл прерывается при запуске исключения .
В ответ на:

sig_atomic_t KEEP_RUNNUNG=1;
void my_handler(){
KEEP_RUNNUNG=0;
printf("my_handler\n");
}
int main(){
struct sigaction sa;
memset(&sa,0,sizeof(sa));
sa.sa_handler=&my_handler;
sigaction(SIGUSR1,&sa,NULL);
while(KEEP_RUNNUNG)
{
printf("action 1\n");
raise(SIGUSR1);
printf("action 2\n");
}
return 0;
}

Или ты хочешь чтоб цикл просто прервался ?
#2 
genocidee посетитель22.10.06 10:04
genocidee
22.10.06 10:04 
in Antwort Chipolino 21.10.06 21:49
Да я хочу чтобы цикл просто прервался, но это должно произоити СРАЗУ по получению сигнала. Если цыкл оооооочень длиный или если там ест блокирующая операции, то цикл не прерывается сразу же, а только когда он проверит условие на входе цикла.
В моем конкретном случае я имею цикл с блокируюцей операцией ввода-вывода внутри библиотечного вызова (Net-SNMP-библиотека) этот блокирующии вызов прерывается только после получения SNMP-пакета. Тоесть если я посылаю сигнал, то ничего не происходит пока не будет получен и обработан очередной SNMP-пакет, а это может занять очень много времени.
Как мне зделать асинхронное прерывание??
Is this the real world, Neo?
#3 
  Smit1970 завсегдатай05.11.06 19:01
NEW 05.11.06 19:01 
in Antwort genocidee 22.10.06 10:04
В ответ на:
Тоесть если я посылаю сигнал, то ничего не происходит пока не будет получен и обработан очередной SNMP-пакет, а это может занять очень много времени. Как мне зделать асинхронное прерывание??

Либо пуллинг при неблокирующем чтении (если с сокетами такое возможно), либо сделать приложение многопоточным (multithread or multiprocess) и использовать один из видов IPC. При реализации multithread можно ставить условные блокировки pthread_cond_wait, срабатывать pthread_cond_signal будет мгновенно. В этом случае можно обойтись без сигналов и хандлеров, которые имеют побочные эффекты (к примеру с хандлерами компилить программу надо с макросом -D_REENTRANT или писать врапперы на SIGINT).
MfG, Smit.
"There is no silver bullet" -- F. Brooks
#4