LINUX.ORG.RU

C, почему теряются сигналы?


0

0

Пытаюсь использовать сигналы, но почему-то они теряются.
Программа, которая это демонстрирует:

#include <signal.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>

int count = 0;
void handler(int s)
{
        ++count;
}

int main(int argc, char *argv[])
{
        int n;
        sigset_t ss;
        struct sigaction sa;
        int i;
        pid_t pid;

        if (argc != 2) {
                fprintf(stderr, "incorrect usage\n");
                return EXIT_FAILURE;
        }
        n = atoi(argv[1]);

        if (sigemptyset(&ss) == -1) {
                perror("sigemptyset");
                return EXIT_FAILURE;
        }

        sa.sa_handler = handler;
        sa.sa_mask = ss;
        sa.sa_flags = 0;
        if (sigaction(SIGUSR1, &sa, NULL) == -1) {
                perror("sigaction");
                return EXIT_FAILURE;
        }

        for (i = 0; i < n && (pid = fork()); ++i)
                ;

        if (pid) {
                while (1) {
                        printf("count before = %d\n", count);
                        /* pause(); */
                        sigsuspend(&ss);
                        printf("count after = %d\n", count);
                }
        }
        else {
                sleep(1);
                if (kill(getppid(), SIGUSR1) == -1) {
                        perror("kill");
                        return EXIT_FAILURE;
                }
        }
        return EXIT_SUCCESS;
}


Результат работы:

% ./test 100                                                                           /home/legioner/work/c/test
count before = 0
count after = 1
count before = 1
count after = 2
count before = 2
count after = 3
count before = 3
count after = 4
count before = 4
count after = 5
count before = 5
count after = 6
count before = 6
count after = 7
count before = 7
count after = 8
count before = 8
count after = 9
count before = 9
count after = 10
count before = 10
count after = 11
count before = 11
count after = 12
count before = 13
count after = 14
count before = 15

И дальше ничего, т.е. 75% сигналов потерялось.
Что я делаю не так?
★★★★★

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

Жаль..

Вопрос снимается.

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

> Ядро не поддерживает очередь сигналов, ожидающих доставки

поддерживает, но для сигналов >= SIGRTMIN

> Жаль..

отнюдь :)

idle ★★★★★
()

Это нормально.
Не буду тебе советовать идти читать Стивенса, или Linux Application
Development или еще какую умную книгу - очевидно у тебя ее нет. Увы.
Поэтому сходи почитай "Signals FAQ" из "RU.UNIX.PROG FAQ".
Там естественно все русском :-)

http://groups.google.com/group/fido7.ru.unix.prog/browse_frm/thread/9cfed5bf1160
477a/1372c640222ddb76#1372c640222ddb76

Небольшая выдержка:
        Между посылкой сигнала и его доставкой может пройти 
        неограниченное количество времени, даже если сигнал не 
        заблокирован.  Следовательно, один и тот же сигнал может 
        быть послан процессу несколько раз перед тем, как он будет 
        доставлен.  Тем не менее, обработчик будет вызван единожды, 
        так как система запоминает только сам факт посылки каждого 
        сигнала.

Этот FAQ относится к "обычным" сигналам и не описывает Realtime 
signals. Я не знаю хорошего online-описания про RT signals, может
кто другой подскажет. В крайнем случае man sigqueue и далее по SEE 
ALSO, или читай SUS.
А лучше всего книжку купи.

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

> Не буду тебе советовать идти читать Стивенса, или Linux Application
> Development или еще какую умную книгу - очевидно у тебя ее нет.
Да, у меня её нет.. Но в сети поищу.

> Поэтому сходи почитай "Signals FAQ" из "RU.UNIX.PROG FAQ".
Спасибо

> Там естественно все русском :-)
Для меня это не очень принципиально, ну ладно.

> А лучше всего книжку купи.
Постараюсь. А какую конкретно посоветуете?

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

> поддерживает, но для сигналов >= SIGRTMIN

Ну мне для SIGUSR1 надо было. Я сделал по другому, просто использовал в нужных местах блокировку сигналов, получилось даже лучше.

По хорошему там надо что-то вроде критических секций делать, но это программа для универа, и по учебной программе мы их ещё не проходили, поэтому приходится с сигналами мучиться.

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