LINUX.ORG.RU

[sleep(3), Си] Остановка по сигналу


0

1

Пусть у меня в программе установлены (через signal) обработчики каких-то сигналов (напр. SIGTERM, SIGUSR1,..). Далее у меня выполняется sleep на 20 сек. Но через 10 секунд программе посылается сигнал. Как я понимаю, переход к обработчику перейдёт сразу. Пусть он быстро обработался. Далее sleep будет продолжать окончания тех 20 секунд или исполнение кода продолжится сразу со следующей после sleep команды?


ЕМНИП все ожидающие функции завершаются, и надо рестартить. Могу говорить ересь

vertexua ★★★★★
()
$ man 3 sleep | grep RETURN -A2
RETURN VALUE
       Zero if the requested time has elapsed, or the number of seconds left to sleep, if the call was interrupted by a signal handler.
geekless ★★
()
Ответ на: комментарий от vertexua

>ЕМНИП все ожидающие функции завершаются, и надо рестартить. Могу говорить ересь

SA_RESTART, но перезапускаются не все функции.

AptGet ★★★
()

У меня на macosx snow leopard вот такой код

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

void sig(int s)
{
        fprintf(stderr, "sss\n");
}

main()
{
        struct sigaction s1 = { sig, 0, SA_RESTART };
        struct sigaction s2 = { sig, 0, SA_RESTART };

        sigaction(SIGINT, &s1, NULL);
//      signal(SIGINT, sig);
        sleep(4);
        fprintf(stderr, "END");
}

прерывает выполнение sleep, хотя и выводит «END».

В мане man sigaction написано:

Restart of pending calls is requested by setting the SA_RESTART bit in sa_flags.  The affected system calls include open(2), read(2),
     write(2), sendto(2), recvfrom(2), sendmsg(2) and recvmsg(2) on a communications channel or a slow device (such as a terminal, but not a regular file) and during a wait(2) or
     ioctl(2).

То есть, sleep не рестартится.

bk_ ★★
()

А usleep и nanosleep уже не так работают? Можно ли с помощью sleep сделать паузу 0,5 с?

toady2
() автор топика
Ответ на: комментарий от toady2

>А usleep и nanosleep уже не так работают? Можно ли с помощью sleep сделать паузу 0,5 с?

man 7 signal, man nanosleep

AptGet ★★★
()
Ответ на: комментарий от toady2

> А usleep и nanosleep уже не так работают?

nanosleep возвращает время, которое недоспал. Соответственно, можно в цикле крутить. И точность выше, чем у sleep - если за двухсекундный интервал придёт десяток сигналов, нанослипом точнее попадёшь.

const86 ★★★★★
()
Ответ на: комментарий от AptGet

Хорошо, если сигнал пришёлся на время выполнения sleep(), то всё ясно. А если он попадёт на «обычный» код, что будет?

Вот, например:

...
void signal_handler(int sig)
{
    if (sig != SIGHUP)
        stop = 1;
}
...
    signal(SIGINT, &signal_handler);
    signal(SIGTERM,&signal_handler);
    signal(SIGQUIT,&signal_handler);
    signal(SIGHUP, &signal_handler);

    for (stop = 0; !stop; sleep(REFRESH_INTERVAL)) {
        snprintf(status, sizeof(status), "%s%s%s",              // (*)
                status_im(), status_mail(), status_time());
        set_status(status);
    }
...
Пусть сигнал пришёл во время исполнения строчки (*). Что может плохого случиться? (statis_im читает файл и возвращает статус пиджина, status_mail открывает почтовый каталог и считает файлы в нём, status_time получает системное время)

toady2
() автор топика
Ответ на: комментарий от toady2

>Пусть сигнал пришёл во время исполнения строчки (*). Что может плохого случиться? (statis_im читает файл и возвращает статус пиджина, status_mail открывает почтовый каталог и считает файлы в нём, status_time получает системное время)

Все зависит от того, как написаны эти функции и какие системные вызовы в них используются. Скорее всего ничего плохого не случится.

AptGet ★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.