sigprocmask() блокирует сигналы в UNIX
Я написал небольшой кусочек кода. Этот код сначала блокирует {SIGSEGV}, затем добавляет SIGRTMIN к тому же набору. Итак, мой последний набор сигналов: {SIGSEGV,SIGRTMIN}. Таким образом, если я использую SIG_UNBLOCK, согласно моему пониманию, сначала должен быть разблокирован SIGRTMIN, а затем снова, если я вызываю SIG_UNBLOCK, SIGSEGV должен быть разблокирован.
1) {SIGSEGV,SIGRTMIN} 2) SIG_UNBLOCK = разблокировать SIGRTMIN, 3) снова вызвать SIG_UNBLOCK = разблокировать SIGSEGV. Я даю процессу только SIGRTMIN, поэтому моя вторая разблокировка должна остановить процесс с помощью SIGRTMIN. Но это не так. Пожалуйста помоги. NB: Пожалуйста, не давайте ссылки на ответы на другие вопросы о sigprocmask(), я их видел, и они не прояснили мой вопрос.
enter code here
#include <signal.h>
#include <unistd.h>
#include <stdio.h>
int main()
{
sigset_t old_set,new_set;
sigemptyset(&old_set);
sigemptyset(&new_set);
if(sigaddset(&old_set,SIGSEGV)==0)
{
printf("sigaddset successfully added for SIGSEGV\n");
}
sigprocmask(SIG_BLOCK,&old_set,NULL); // SIGSEGV signal is masked
kill(0,SIGSEGV);
//*****************************************************************
if(sigaddset(&new_set,SIGRTMIN)==0)
{
printf("sigaddset successfully added for SIGRTMIN\n");
}
sigprocmask(SIG_BLOCK,&new_set,&old_set); // SIGRTMIN signal is masked
kill(0,SIGSEGV);
//****************** Unblock one signal at a time ******************
sigprocmask(SIG_UNBLOCK,&new_set,&old_set); // SIGRTMIN signal is unmasked
sigprocmask(SIG_UNBLOCK,&new_set,&old_set); // SIGSEGV signal is unmasked
}
Output:
[root@dhcppc0 signals]# ./a.out
sigaddset successfully added for SIGSEGV
sigaddset successfully added for SIGRTMIN
(Note:SIGSEGV is not received even after sigprocmask(SIG_UNBLOCK,&new_set,&old_set); a second time)
2 ответа
Ваша предпосылка неверна. Весь набор блокируется и разблокируется с помощью одного вызова sigprocmask
,
Кроме того, обычно вы создаете набор, содержащий каждый сигнал, который хотите заблокировать, а затем пытаетесь заблокировать их все с помощью sigprocmask(SIG_BLOCK, pointer_to_sigset);
,
Ваш код на самом деле не разблокирует SIGSEGV. Вот что я бы написал БЕЗ обработки ошибок, потому что это сделало бы фрагмент без необходимости длинным. Проверьте каждую функцию на наличие ошибок, однако списки возможных ошибок представлены на страницах руководства:
/* ... */
sigset_t signal_set; /* We don't need oldset in this program. You can add it,
but it's best to use different sigsets for the second
and third argument of sigprocmask. */
sigemptyset(&signal_set);
sigaddset(&signal_set, SIGSEGV);
sigaddset(&signal_set, SIGRTMIN);
/* now signal_set == {SIGSEGV, SIGRTMIN} */
sigprocmask(SIG_BLOCK, &signal_set, NULL): /* As i said, we don't bother with the
oldset argument. */
kill(0,SIGSEGV);
kill(0,SIGSEGV); /* SIGSEGV is not a realtime signal, so we can send it twice, but
it will be recieved just once */
sigprocmask(SIG_UNBLOCK, &signal_set, NULL); /* Again, don't bother with oldset */
/* SIGSEGV will be received here */
Конечно, вы можете разделить блокировку сигналов на две операции на отдельных наборах. Механизм работает следующим образом: есть некоторый набор заблокированных сигналов, который заменит oldset, если вы предоставите аргумент oldset. Вы можете добавить к этому набору SIG_BLOCK
удалить из этого набора с помощью SIG_UNBLOCK
и измените весь набор по своему вкусу с помощью SIG_SETMASK
аргументы sigprocmask
функция.
Как отметил Куби: вот модифицированный код, проблема в том, что я перепутал со старыми и новыми. SIGSEGV был добавлен в old_set, который не был разблокирован, и, следовательно, я не получил ошибку сегментации (сигнал SIGSEGV). Спасибо Куби.
enter code here
#include <signal.h>
#include <unistd.h>
#include <stdio.h>
int main()
{
sigset_t old_set,new_set;
sigemptyset(&old_set);
sigemptyset(&new_set);
if(sigaddset(&old_set,SIGSEGV)==0)
{
printf("sigaddset successfully added for SIGSEGV\n");
}
sigprocmask(SIG_BLOCK,&new_set,&old_set); // SIGSEGV signal is masked
kill(0,SIGSEGV);
//*****************************************************************
if(sigaddset(&new_set,SIGRTMIN)==0)
{
printf("sigaddset successfully added for SIGRTMIN\n");
}
if(sigprocmask(SIG_BLOCK,&new_set,&old_set)==-1) // SIGRTMIN signal is masked
{
perror("sigprocmask");
}
kill(0,SIGSEGV);
//****************** Unblock all signals ******************
if(sigprocmask(SIG_UNBLOCK,&new_set,&old_set)==-1) // SIGRTMIN signal is unmasked
{
perror("sigprocmask");
}
}