- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
学习信号后,我想知道过程信号掩码,阻塞的信号集,信号处理程序和阻塞的信号之间的细微差别。
问题涉及(在Debian上):
#include <string.h>
#include <signal.h>
void show_signals(const sigset_t exmask)
{
int exsignals[43];
exsignals[0] = SIGABRT;
exsignals[1] = SIGALRM;
exsignals[2] = SIGBUS;
exsignals[3] = SIGCHLD;
exsignals[4] = SIGCONT;
#ifdef SIGEMT
exsignals[5] = SIGEMT;
#else
exsignals[5] = -1;
#endif
exsignals[6] = SIGFPE;
#ifdef SIGFREEZE
exsignals[7] = SIGFREEZE;
#else
exsignals[7] = -1;
#endif
exsignals[8] = SIGHUP;
exsignals[9] = SIGILL;
#ifdef SIGINFO
exsignals[10] = SIGINFO;
#else
exsignals[10] = -1;
#endif
exsignals[11] = SIGINT;
exsignals[12] = SIGIO;
exsignals[13] = SIGIOT;
#ifdef SIGJVM1
exsignals[14] = SIGJVM1;
#else
exsignals[14] = -1;
#endif
#ifdef SIGJVM2
exsignals[15] = SIGJVM2;
#else
exsignals[15] = -1;
#endif
exsignals[16] = SIGKILL;
#ifdef SIGLOST
exsignals[17] = SIGLOST;
#else
exsignals[17] = -1;
#endif
#ifdef SIGLWP
exsignals[18] = SIGLWP;
#else
exsignals[18] = -1;
#endif
exsignals[19] = SIGPIPE;
exsignals[20] = SIGPOLL;
exsignals[21] = SIGPROF;
exsignals[22] = SIGPWR;
exsignals[23] = SIGQUIT;
exsignals[24] = SIGSEGV;
exsignals[25] = SIGSTKFLT;
exsignals[26] = SIGSTOP;
exsignals[27] = SIGSYS;
exsignals[28] = SIGTERM;
#ifdef SIGTHAW
exsignals[29] = SIGTHAW;
#else
exsignals[29] = -1;
#endif
#ifdef SIGTHR
exsignals[30] = SIGTHR;
#else
exsignals[30] = -1;
#endif
exsignals[31] = SIGTRAP;
exsignals[32] = SIGTSTP;
exsignals[33] = SIGTTIN;
exsignals[34] = SIGTTOU;
exsignals[35] = SIGURG;
exsignals[36] = SIGUSR1;
exsignals[37] = SIGUSR2;
exsignals[38] = SIGVTALRM;
#ifdef SIGWAITING
exsignals[39] = SIGWAITING;
#else
exsignals[39] = -1;
#endif
exsignals[40] = SIGWINCH;
exsignals[41] = SIGXCPU;
exsignals[42] = SIGXFSZ;
#ifdef SIGXRES
exsignals[43] = SIGXRES;
#else
exsignals[43] = -1;
#endif
int exsignals_n = 0;
for (;exsignals_n < 43; exsignals_n++) {
if (exsignals[exsignals_n] == -1) continue;
static char *exsignal_name;
exsignal_name = strsignal(exsignals[exsignals_n]);
switch(sigismember(&exmask, exsignals[exsignals_n]))
{
case 0: break;
case 1: printf("YES %s\n", exsignal_name); break;
case -1: printf("could not obtain signal\n"); break;
default: printf("UNEXPECTED for %s return\n", exsignal_name); break;
}
}
}
const sigset_t getmask(void)
{
static sigset_t retmask;
if ((sigprocmask(SIG_SETMASK, NULL, &retmask)) == -1)
printf("could not obtain process signal mask\n");
return retmask;
}
static void sig_abrt(int signo)
{
printf("Caught SIGABRT\n");
}
int main(void)
{
show_signals(getmask());
signal(SIGABRT, sig_abrt);
show_signals(getmask());
return 0;
}
最佳答案
Each process has it's [sic] own signal mask (a long which contains the signals being blocked)
pthread_sigmask()
来操作当前线程的信号掩码;在单线程程序中,可以使用
sigprocmask()
。)
sigset_t
,它可以是数组,结构或 union 类型。在任何情况下,都应该简单地将其视为无序位集,每个信号一位。
So now there is a signal handler for SIGABRT, but SIGABRT will not be in the process signal mask.
If I block SIGABRT with sigaddset(3), will the signal handler sig_abrt not receive the call when the SIGABRT is delivered? Does it mean that the signal mask affects which signals are delivered? What is the difference?
sigwait()
,
sigwaitinfo()
或
sigtimedwait()
消耗了信号,则根本不会调用信号处理程序。
kill()
或pid == 0
的 pid == -pgid
),特定进程(pid
)或特定进程中的特定线程(同一进程中的 pthread_kill()
,通常是Linux中的 tgkill
系统调用)。 SIG_IGN
“handler”)或man 7 signal
。 sigwait()
, sigwaitinfo()
或 sigtimedwait()
。这些功能检查是否有任何信号挂起,如果有,则“捕获”。他们检查的信号集由sigset_t
类型的功能参数定义。 sigwait()
,
sigwaitinfo()
或
sigtimedwait()
,则它将接收有关该信号的信息,并捕获该信号。 (它将不再挂起,也不会导致信号处理程序被调用;它是“消耗的”。)
Also, is there a way to block a signal in a process without using the sigsetops(3) and sigprocmask(2) functions?
sigsetops()
和
sigprocmask()
的syscall包装器,仅此而已。)
#define _POSIX_C_SOURCE 200809L
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <stdio.h>
#include <errno.h>
/* Async-signal safe write-to-standard error function.
Keeps errno unchanged. Do not use stderr otherwise!
*/
static int wrerrpp(const char *ptr, const char *end)
{
const int saved_errno = errno;
ssize_t chars;
while (ptr < end) {
chars = write(STDERR_FILENO, ptr, (size_t)(end - ptr));
if (chars > 0)
ptr += chars;
else
if (chars != -1) {
errno = saved_errno;
return EIO;
} else
if (errno != EINTR) {
const int retval = errno;
errno = saved_errno;
return retval;
}
}
errno = saved_errno;
return 0;
}
/* Write the supplied string to standard error.
Async-signal safe. Keeps errno unchanged.
Do not mix with stderr!
*/
static int wrerr(const char *ptr)
{
if (!ptr)
return 0;
else {
const char *end = ptr;
/* strlen() is not async-signal safe, so
find the end of the string the hard way. */
while (*end)
end++;
return wrerrpp(ptr, end);
}
}
/* Write the supplied long to standard error.
Async-signal safe. Keeps errno unchanged.
Do not mix with stderr!
*/
static int wrerrnum(const long value)
{
unsigned long u = (value < 0) ? (unsigned long)-value : (unsigned long)value;
char buf[40];
char *ptr = buf + sizeof buf;
char *const end = buf + sizeof buf;
do {
*(--ptr) = '0' + (u % 10uL);
u /= 10uL;
} while (u > 0uL);
if (value < 0)
*(--ptr) = '-';
return wrerrpp(ptr, end);
}
/* Async-signal safe variant of strsignal().
Only covers a small subset of all signals.
Returns NULL if the signal name is not known. */
static const char *signal_name(const int signum)
{
switch (signum) {
case SIGHUP: return "HUP";
case SIGINT: return "INT";
case SIGQUIT: return "QUIT";
case SIGKILL: return "KILL";
case SIGSEGV: return "SEGV";
case SIGTERM: return "TERM";
case SIGUSR1: return "USR1";
case SIGUSR2: return "USR2";
case SIGCHLD: return "CHLD";
case SIGCONT: return "CONT";
case SIGSTOP: return "STOP";
default: return NULL;
}
}
/* Signal handler that reports its delivery immediately,
but does nothing else.
*/
static void report_signal(int signum, siginfo_t *info, void *ctx)
{
const char *sname = signal_name(signum);
wrerr("report_signal(): Received signal ");
if (sname)
wrerr(sname);
else
wrerrnum(signum);
if (info->si_pid) {
wrerr(" from process ");
wrerrnum(info->si_pid);
wrerr(".\n");
} else
wrerr(" from kernel or terminal.\n");
}
/* Install report_signal() handler.
*/
static int install_report_signal(const int signum)
{
struct sigaction act;
memset(&act, 0, sizeof act);
sigemptyset(&act.sa_mask);
act.sa_sigaction = report_signal;
act.sa_flags = SA_SIGINFO;
if (sigaction(signum, &act, NULL) == -1)
return errno;
return 0;
}
int main(void)
{
sigset_t mask;
siginfo_t info;
const char *name;
int signum;
if (install_report_signal(SIGINT) ||
install_report_signal(SIGCONT)) {
const char *errmsg = strerror(errno);
wrerr("Cannot install signal handlers: ");
wrerr(errmsg);
wrerr(".\n");
return EXIT_FAILURE;
}
sigemptyset(&mask);
sigaddset(&mask, SIGUSR1);
sigaddset(&mask, SIGUSR2);
sigaddset(&mask, SIGHUP);
sigaddset(&mask, SIGTERM);
sigprocmask(SIG_SETMASK, &mask, NULL);
printf("Process %ld is ready to receive signals! Run\n", (long)getpid());
printf("\tkill -USR1 %ld\n", (long)getpid());
printf("\tkill -USR2 %ld\n", (long)getpid());
printf("\tkill -HUP %ld\n", (long)getpid());
printf("\tkill -TERM %ld\n", (long)getpid());
printf("in another terminal; press Ctrl+C in this terminal; or press Ctrl+Z and run\n");
printf("\tfg\n");
printf("in this terminal.\n");
fflush(stdout);
/* Almost same as blocked mask, just without SIGUSR1 and SIGUSR2. */
sigemptyset(&mask);
sigaddset(&mask, SIGHUP);
sigaddset(&mask, SIGTERM);
do {
do {
signum = sigwaitinfo(&mask, &info);
} while (signum == -1 && errno == EINTR);
if (signum == -1) {
const char *errmsg = strerror(errno);
wrerr("sigwaitinfo(): ");
wrerr(errmsg);
wrerr(".\n");
return EXIT_FAILURE;
}
name = signal_name(signum);
if (name)
printf("main(): Received signal %s from ", name);
else
printf("main(): Received signal %d from ", signum);
if (info.si_pid == 0)
printf("kernel or terminal.\n");
else
printf("process %ld.\n", (long)info.si_pid);
fflush(stdout);
} while (signum != SIGTERM);
return EXIT_SUCCESS;
}
gcc -Wall -O2 example.c -o example
./example
Process 843 is ready to receive signals! Run
kill -USR1 843
kill -USR2 843
kill -HUP 843
kill -TERM 843
in another terminal; press Ctrl+C in this terminal; or press Ctrl+Z and run
fg
in this terminal.
report_signal()
信号处理程序传递。)
./example
插入作业控制之下,并让您输入新的Shell命令。
fg
命令将
./example
带回到前台,然后 shell 程序将CONT信号发送给它,以便
./example
继续执行。
report_signal()
信号处理程序。
sigwaitinfo()
接收。
关于c - 过程信号掩码,阻塞信号集和阻塞信号之间的区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48409070/
所以我目前正在研究 C 中的 POSIX 线程和信号编程。我的讲师使用 sigset(int sigNumber, void* signalHandlerFUnction) 因为他的笔记不是世界上最好
我正在制作一个 C++ 游戏,它要求我将 36 个数字初始化为一个 vector 。你不能用初始化列表初始化一个 vector ,所以我创建了一个 while 循环来更快地初始化它。我想让它把每个数字
我正在尝试让 Python 发送 EOF信号 (Ctrl+D) 通过 Popen() .不幸的是,我找不到任何关于 Popen() 的引用资料。 *nix 类系统上的信号。这里有谁知道如何发送 EOF
我正在尝试让 Python 发送 EOF信号 (Ctrl+D) 通过 Popen() .不幸的是,我找不到任何关于 Popen() 的引用资料。 *nix 类系统上的信号。这里有谁知道如何发送 EOF
我正在学习编码并拥有一个实时的 Django 项目来保持我的动力。在我的 Django 应用程序中,用户留下评论,而其他人则回复所述评论。 每次用户刷新他们的主页时,我都会计算他们是否收到了关于他们之
登录功能中的django信号有什么用?用户已添加到请求 session 表中。那么 Django auth.login 函数中对信号的最后一行调用是什么? @sensitive_post_param
我已经将用户的创建与函数 create_user_profile 连接起来,当我创建我的用户时出现问题,我似乎连接的函数被调用了两次,而 UserProfile 试图被创建两次,女巫触发了一个错误 列
我有一个来自生产者对象处理的硬件的实时数据流。这会连接到一个消费者,该消费者在自己的线程中处理它以保持 gui 响应。 mainwindow::startProcessing(){ QObje
在我的 iPhone 应用程序中,我想提供某种应用程序终止处理程序,该处理程序将在应用程序终止之前执行一些最终工作(删除一些敏感数据)。 我想尽可能多地处理终止情况: 1) 用户终止应用 2) 设备电
我试图了解使用 Angular Signals 的优势。许多解释中都给出了计数示例,但我试图理解的是,与我下面通过变量 myCount 和 myCountDouble 所做的方式相比,以这种方式使用信
我对 dispatch_uid 的用法有疑问为信号。 目前,我通过简单地添加 if not instance.order_reference 来防止信号的多次使用。 .我现在想知道是否dispatch
有时 django 中的信号会被触发两次。在文档中,它说创建(唯一)dispatch_uid 的一个好方法是模块的路径或名称[1] 或任何可哈希对象的 ID[2]。 今天我尝试了这个: import
我有一个用户定义的 shell 项目,我试图在其中实现 cat 命令,但允许用户单击 CTRL-/ 以显示下一个 x 行。我对信号很陌生,所以我认为我在某个地方有一些语法错误...... 主要...
http://codepad.org/rHIKj7Cd (不是全部代码) 我想要完成的任务是, parent 在共享内存中写入一些内容,然后 child 做出相应的 react ,并每五秒写回一些内容
有没有一种方法可以找到 Qt 应用程序中信号/槽连接的总数有人向我推荐 Gamma 射线,但有没有更简单的解决方案? 最佳答案 检查 Qt::UniqueConnection . This is a
我正在实现一个信号/插槽框架,并且到了我希望它是线程安全的地步。我已经从 Boost 邮件列表中获得了很多支持,但由于这与 boost 无关,我将在这里提出我的未决问题。 什么时候信号/槽实现(或任何
在我的代码中,我在循环内创建相同类型的新对象并将信号连接到对象槽。这是我的试用版。 A * a; QList aList; int aCounter = 0; while(aCounter aLis
我知道 UNIX 上的 C 有 signal() 可以在某些操作后调用某些函数。我在 Windows 上需要它。我发现了,它存在什么 from here .但是我不明白如何正确使用它。 我在 UNIX
目前我正在将控制台 C++ 项目移植到 Qt。关于移植,我有一些问题。现在我的项目调整如下我有一个派生自 QWidget 的 Form 类,它使用派生自 QObject 的其他类。 现在请告诉我我是否
在我的 Qt 多线程程序中,我想实现一个基于 QObject 的基类,以便从它派生的每个类都可以使用它的信号和槽(例如抛出错误)。 我实现了 MyQObject : public QObject{..
我是一名优秀的程序员,十分优秀!