LINUX.ORG.RU

Идиотский вопрос по сигналам

 , ,


0

3

Претендую на самый идиотский вопрос по сигналам в программировании под Linux в частности, и под POSIX....

Есть прекрасные сигналы SIGUSR1 и SIGUSR2, но их жалко - их всего два. Они стандартно определены.

Могу ли я использовать свои сигналы, которые нигде не описаны (ну или я этого не нашёл)... например:

#define SIGUSR3_MUTHER_FUCKER (123)

★★★★★

Могу ли я использовать свои сигналы, которые нигде не описаны

это вряд ли. Но есть «лазейка»: если сигналы передаются внутри твоего софта (любые, ну почти), то и реакция на них может быть любой необходимой тебе. // Так делать нельзя, это плохо

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

Только если согласуешь с ядром и glibc.

А причём тут ядро и glibc(которое не используется), когда я это шлю конкретному pid`у, который знает что с этим сигналом делать?

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

Но есть «лазейка»: если сигналы передаются внутри твоего софта (любые, ну почти), то и реакция на них может быть любой необходимой тебе. // Так делать нельзя, это плохо

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

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

Механизм передачи сигналов межу процессами реализован в ядре, а в либси пользовательские функции для этого. Список поддерживаемых сигналов определён в тоже ядре, насколько я помню. Если хочешь саои сигналы – надо править ядро.

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

А причём тут ядро и glibc(которое не используется), когда я это шлю конкретному pid`у, который знает что с этим сигналом делать?

Среда исполнения, которая знает, что такое «сигналы», «потоки» и прочие стандартные штуки, описанные в POSIX - находится в ядре.

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

Это что-то новенькое. Про пчёлку слышал?

тот же dd использует SIGUSR1 (показ прогресса) и SIGUSR2 (завершение) для удобства юзверей в консоли.
1. Им намного приятней писать kill SIGUSR1 pid_of_your_prog чем kill 123 pid_of_your_prog
2. консольный kill посылает «левые» сигналы нафиг - защита от дурака, но мне для использования для сист. вызова - юзер и не должен знать о них ничего.

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

Вот тебе, кстати, табличка со значениями констант для разных ОС.

Это просто дефайны, описанные в стандартах. Что мешает мне прописать kill(otherPID,9), вместо kill(otherPID, SIGKILL)?

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

Что мешает мне прописать kill(otherPID,9), вместо kill(otherPID, SIGKILL)?

Ничего не мешает. SIGKILL отработает на уровне ядра и убьёт твой процесс.

А вообще ты уже куда-то далеко отошел от исходной постановки вопроса.

То ты не хотел использовать стандартные сигналы, то готов их переопределить.

wandrien ★★★
()
Последнее исправление: wandrien (всего исправлений: 1)
Ответ на: комментарий от wandrien

То ты не хотел использовать стандартные сигналы, то готов их переопределить.

Это вы со своей болтологией путаете мысли. Это был отвтет на твою «стандартную табличку»

Что мне мешает вызвать kill(otherPID,123), если процесс с otherPID заранее поставил обработчик на 123 через банальный signal(123, my_fucking_handler)?

drfaust ★★★★★
() автор топика
Последнее исправление: drfaust (всего исправлений: 1)
Ответ на: комментарий от drfaust

Тем, что в банальной реализации signal(2) не предусмотрено существование 123-го сигнала.

ERRORS
       EINVAL signum is invalid.
wandrien ★★★
()
Последнее исправление: wandrien (всего исправлений: 1)
Ответ на: комментарий от wandrien

От теперь понятно. Вопрос вроде закрыт.

Т.е. размер таблицы обработчиков сигналов для каждого процесса захардкорен и не может превышать, судя по мануалам SIGRTMAX (64)...

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

Realtime сигналы передаются с более высоким приоритетом, чем обычные, не могут быть потеряны. Их использование в своём софте не по назначению может привести к повышенной нагрузке на систему.

Aceler ★★★★★
()

Почему именно сигналы? Есть сотня других IPC, с нормальным представлением и передачей данных в размере более одного бита.

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

ты это читал?

https://man7.org/linux/man-pages/man7/signal.7.html

там «рилтайм сигналы» от 3x до 63, и ведут себя как стандартные.


The Linux kernel supports a range of 33 different real-time
       signals, numbered 32 to 64.  However, the glibc POSIX threads
       implementation internally uses two (for NPTL) or three (for
       LinuxThreads) real-time signals (see pthreads(7)), and adjusts
       the value of SIGRTMIN suitably (to 34 or 35).  Because the range
       of available real-time signals varies according to the glibc
       threading implementation (and this variation can occur at run
       time according to the available kernel and glibc), and indeed the
       range of real-time signals varies across UNIX systems, programs
       should never refer to real-time signals using hard-coded numbers,
       but instead should always refer to real-time signals using the
       notation SIGRTMIN+n, and include suitable (run-time) checks that
       SIGRTMIN+n does not exceed SIGRTMAX.
alysnix ★★★
()
Последнее исправление: alysnix (всего исправлений: 1)
Ответ на: комментарий от Aceler

Использование разовое. «о-o-o-o-чень редко» пнуть программу в нужном направлении другой программой. Держать для этого канал или сокет не вариант. Файл типа pid.lock вообще не вариант. Постоянно просматривать shm - отдельный поток нужен будет.

З.Ы. Я вообще от IPC даже в виде сигналов планирую избавится, но, пока не придумал как.

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

Так можно совместить. Создать файл, в котором будет описано, в каком именно направлении, и проверять этот файл по SIGUSR1. Но нужно быть осторожным с async signal safety в функциях (man signal-safety) и с возможным прерыванием системных вызовов. В частности, использовать read вместо fread и блокировать сигналы перед системными вызовами, прерывание которых нежелательно (не забыв разблокировать их после этого).

PeachBlossoms
()
Последнее исправление: PeachBlossoms (всего исправлений: 1)
Ответ на: комментарий от PeachBlossoms

Это совсем не то, что я хочу. Где этот файл создавать? Где его другой проге с флешки запущенной искать?

З.Ы. И вообще, в идеале отказаться от IPC, использовать только то, что извесно по pid и текущему uid - пока думаю как и что делать... Потому и возник вопрос в сторону сигналов.

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

The GNU libc manual documents the original POSIX specification for signal handling functions. However subsequent POSIX standards expanded this functionality and the enhancements are often referred to as «realtime signals».

Никто и не утверждал, что они будут иметь к-то приоритет в линухе

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

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

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

не могут быть потеряны

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

Этот код у меня выводит 15608, хотя, если они «не могут быть потеряны», то должно быть 100000.

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

static int n = 0;

static void sighandler(int signo)
{
    (void) signo;
    for (int i = 0; i < 100000; ++i) {
        asm volatile ("" ::: "memory");
    }   
    ++n;
}   

int main()
{
    signal(SIGRTMIN, sighandler);
    
    pid_t parent = getpid();
    
    pid_t child = fork();
    if (child < 0) {
        perror("fork");
        return 1;
        
    } else if (child == 0) {
        for (int i = 0; i < 100000; ++i) {
            kill(parent, SIGRTMIN); 
        }   
        return 0;
        
    } else {
        waitpid(child, NULL, 0);
        sleep(5);
        printf("%d\n", n);
        return 0;
    }   
}   
cudeta
()
Последнее исправление: cudeta (всего исправлений: 1)
Ответ на: комментарий от drfaust

Я сам до этого треда понятия не имел какие там ограничения =)

Мысли в слух вероятно придурковатые.

Ну наверное можно сделать финтом если ты хочешь из вне посылать сигналы, но разные своему приложению , основная программа при своём запуске делает mkfifo('my_signal_fifo_info_channel'...) и обработчик SIGUSR1 который при своём вызове читает из FIFO информацию чего его там дрыгнули получая код 100500 и по своей табличке смотрит, ага мне послали сигнал 100500 буду делать то-то, мне послали сигнал 100501 буду делать уже вот это.


В программе которая посылает сигнал открывается my_signal_fifo_info_channel и в него пишется 100500,100501 типа

mykill UPDATE_ALL_METRICS где UPDATE_ALL_METRICS == 100500 и оно же вшито в основной программе, ну или просто числом передавать.


Да, у тебя будет прибитая гвоздями связка из основной программы + программы посылающей её сигнал. Но зато ты получаешь по сути гибкое межпроцессорное взаимодействие с фичёй сигнала прервать процесс для выполнения срочных действий. Или типа того.

Да вторую программу писать вообще не обязательно, можно и без того в конкретный пайп писать. Но, хотя чё но, норм. Ну разве что как избежания от ошибок не мусор слать, а конкретные «сигналы», а мусор не пускать, тогда отдельная приложенька.

LINUX-ORG-RU ★★★★★
()
Последнее исправление: LINUX-ORG-RU (всего исправлений: 1)
Ответ на: комментарий от LINUX-ORG-RU

Я сам до этого треда понятия не имел какие там ограничения =)

Да, у тебя будет прибитая гвоздями связка из основной программы + программы посылающей её сигнал. Но зато ты получаешь по сути гибкое межпроцессорное взаимодействие с фичёй сигнала прервать процесс для выполнения срочных действий.

Да я пока упоролся по shared memory (объёмы мелкие), но «подконтрольному» процессу надо как-то отслеживать что от него хотят, а поток это излишество, неблокирующее чтение с тучей ресурсов так же. Если в винде хватает WinAPI и я могу даже из другой проги фон чужого окна поменять, зная HWND, то в *nix всё по-разному.

drfaust ★★★★★
() автор топика

FWIW, вместо сигналов можно использовать eventfd и передавать любые 64-битные коды. Но это

  • (пока ещё) не POSIX, хотя его завезли в *BSD и многие другие *nix, см. https://www.gnu.org/software/gnulib/manual/html_node/eventfd.html
  • модель работы у этой штуки аналогична пайпам и сокетам, т.е. никакой асинхронщины. Хотя это для большинства ситуаций только плюс, кмк.
annulen ★★★★★
()

Ну и стоит упомянуть типичный паттерн при работе с сигналами: при получении сигнала программа может прочитать дополнительные данные из какого-то другого источника. Например, общепринятым поведением для демонов является перечитка конфигурационных файлов при получении SIGHUP.

annulen ★★★★★
()

man 1 kill:

-q, --queue value
   Send the signal using sigqueue(3) rather than kill(2). The value
   argument is an integer that is sent along with the signal. If the
   receiving process has installed a handler for this signal using the
   SA_SIGINFO flag to sigaction(2), then it can obtain this data via the
   si_sigval field of the siginfo_t structure.

Кстати, kill(1) не шлёт сигналы, кроме тех, что перечислены в kill -l.

anonymous
()
23 декабря 2023 г.

Где-то читал, что для пользовательских сигналов выделен диапазон 128-255. И вроде как его соблюдают, но не во всех системах. В 99% они не будут пересекаться с ядерными, но в 1% - если ядроделы отошли от рекомендации, будут проблемы.

Но это неточно.

Xintrea ★★★★★
()