广州招聘网网站开发,设计开发程序,如何确定竞争对手网站,无代码开发小程序信号是对进程的通知#xff0c;指示事件的发生。信号也称为软件中断#xff0c;无法预知其发生#xff0c;因此也称为异步事件。
可以用数字或名称指定信号#xff0c;通常信号名称以SIG开头。可用信号kill –l(列出信号名称为l)检查可用信号#xff0c;如下所示- 无论何…
信号是对进程的通知指示事件的发生。信号也称为软件中断无法预知其发生因此也称为异步事件。
可以用数字或名称指定信号通常信号名称以SIG开头。可用信号kill –l(列出信号名称为l)检查可用信号如下所示- 无论何时发出信号都会执行默认操作忽略信号意味着既不执行默认操作也不处理信号几乎可以忽略或处理所有信号。不可忽略或无法处理/捕获的信号是SIGSTOP和SIGKILL。
总而言之对信号执行的操作如下-
默认操作处理信号忽略信号
如所讨论的可以改变默认动作的执行来处理信号信号处理可以两种方式之一进行即通过系统调用signal()和sigaction()。
#include signal.htypedef void (*sighandler_t) (int);
sighandler_t signal(int signum, sighandler_t handler);
系统调用signal()将在信号产生时调用注册处理程序如信号传递中所述。处理程序可以是SIG_IGN(忽略信号)SIG_DFL(将信号设置回默认机制)或用户定义的信号处理程序或函数地址之一。
成功的系统调用将返回带有整数参数且没有返回值的函数的地址。如果发生错误此调用将返回SIG_ERR。
尽管可以使用signal()调用由用户注册的相应信号处理程序但无法进行微调例如屏蔽应阻止的信号修改信号的行为以及其他功能。使用sigaction()系统调用可以做到这一点。
#include signal.hint sigaction(int signum, const struct sigaction *act, struct sigaction *oldact)
该系统调用用于检查或更改信号动作如果该动作不为空则从该动作安装信号信号的新动作。如果oldact不为null则先前的操作将保存在oldact中。
sigaction结构包含以下字段-
字段1 - 在sa_handler或sa_sigaction中提到的处理程序。
void (*sa_handler)(int);
void (*sa_sigaction)(int, siginfo_t *, void *);
sa_handler的处理程序基于符号指定要执行的操作其中SIG_DFL表示默认操作而SIG_IGN则忽略信号或指向信号处理功能的指针。
sa_sigaction的处理程序将信号编号指定为第一个参数将siginfo_t结构的指针指定为第二个参数将用户上下文的指针指定为第三个参数(请检查getcontext()或setcontext()以获取更多信息)。
结构siginfo_t包含信号信息例如要传送的信号编号信号值进程ID发送进程的实际用户ID等。
字段2 - 要阻止的信号集。
int sa_mask;
此变量指定在执行信号处理程序期间应屏蔽的信号掩码。
字段3 - 特殊标志。
int sa_flags;
该字段指定一组标志这些标志可修改信号的行为。
字段4 - 还原处理程序。
void (*sa_restorer) (void);
成功时此系统调用返回0失败时返回-1。
让我们考虑一些示例程序。
首先让我们从产生异常的示例程序开始在此程序中我们尝试执行零除运算这会使系统生成异常。
/* signal_fpe.c */
#includestdio.hint main() {int result;int v1, v2;v1 121;v2 0;result v1/v2;printf(Result of Divide by Zero is %d\n, result);return 0;
}
编译和执行步骤
Floating point exception (core dumped)
因此当我们尝试执行算术运算时系统生成了带有核心转储的浮点异常这是信号的默认操作。
现在让我们使用signal()系统调用来修改代码以处理此特定信号。
/* signal_fpe_handler.c */
#includestdio.h
#includesignal.h
#includestdlib.hvoid handler_dividebyzero(int signum);int main() {int result;int v1, v2;void (*sigHandlerReturn)(int);sigHandlerReturn signal(SIGFPE, handler_dividebyzero);if (sigHandlerReturn SIG_ERR) {perror(Signal Error: );return 1;}v1 121;v2 0;result v1/v2;printf(Result of Divide by Zero is %d\n, result);return 0;
}void handler_dividebyzero(int signum) {if (signum SIGFPE) {printf(Received SIGFPE, Divide by Zero Exception\n);exit (0);} elseprintf(Received %d Signal\n, signum);return;
}
编译和执行步骤
Received SIGFPE, Divide by Zero Exception
如所讨论的信号是由系统生成的或者用户也可以通过编程方式生成信号如果要以编程方式生成信号请使用库函数raise()。
要继续执行已停止的进程请将SIGCONT发送到该特定进程。您还可以发出fg(前景)或bg(背景)命令以继续执行在这里这些命令只会重新开始最后一个进程的执行。如果停止了多个进程则仅恢复最后一个进程。如果要恢复以前停止的进程请恢复作业(使用fg/bg)以及作业号。
以下程序用于通过raise()函数引发信号SIGSTOP。用户按下CTRL Z(Control Z)键也可以生成信号SIGSTOP。发出该信号后程序将停止执行。发送信号(SIGCONT)以继续执行。
在以下示例中我们将使用命令fg恢复停止的进程。
/* signal_raising.c */
#includestdio.h
#includesignal.h
#includestdlib.hint main() {printf(Testing SIGSTOP\n);raise(SIGSTOP);return 0;
}
编译和执行步骤
Testing SIGSTOP
[1] Stopped ./a.out
./a.out
现在通过从另一个终端发出SIGCONT增强先前的程序以继续执行已停止的进程。
/* signal_stop_continue.c */
#includestdio.h
#includesignal.h
#include sys/types.h
#include unistd.hvoid handler_sigtstp(int signum);int main() {pid_t pid;printf(Testing SIGSTOP\n);pid getpid();printf(Open 另一个码头 and issue following command\n);printf(kill -SIGCONT %d or kill -CONT %d or kill -18 %d\n, pid, pid, pid);raise(SIGSTOP);printf(Received signal SIGCONT\n);return 0;
}
编译和执行步骤
Testing SIGSTOP
Open 另一个码头 and issue following command
kill -SIGCONT 30379 or kill -CONT 30379 or kill -18 30379
[1] Stopped ./a.outReceived signal SIGCONT
[1] Done ./a.out
在另一个终端
kill -SIGCONT 30379
到目前为止我们已经看到了处理系统生成的信号的程序。现在让我们看看通进程序(使用raise()函数或通过kill命令)生成的信号。该程序生成信号SIGTSTP(终端停止)其默认操作是停止执行。但是由于我们现在正在处理信号而不是默认操作因此它将到达已定义的处理程序。在这种情况下我们只是打印消息并退出。
/* signal_raising_handling.c */
#includestdio.h
#includesignal.h
#includestdlib.hvoid handler_sigtstp(int signum);int main() {void (*sigHandlerReturn)(int);sigHandlerReturn signal(SIGTSTP, handler_sigtstp);if (sigHandlerReturn SIG_ERR) {perror(Signal Error: );return 1;}printf(Testing SIGTSTP\n);raise(SIGTSTP);return 0;
}void handler_sigtstp(int signum) {if (signum SIGTSTP) {printf(Received SIGTSTP\n);exit(0);}elseprintf(Received %d Signal\n, signum);return;
}
编译和执行步骤
Testing SIGTSTP
Received SIGTSTP
我们已经看到了执行默认操作或处理信号的实例。现在该忽略信号了。在这里在此示例程序中我们通过SIG_IGN注册了要忽略的信号SIGTSTP然后提高了信号SIGTSTP(终端停止)。当信号SIGTSTP产生时将被忽略。
/* signal_raising_ignoring.c */
#includestdio.h
#includesignal.h
#includestdlib.hvoid handler_sigtstp(int signum);int main() {void (*sigHandlerReturn)(int);sigHandlerReturnsignal(SIGTSTP, SIG_IGN);if (sigHandlerReturn SIG_ERR) {perror(Signal Error: );return 1;}printf(Testing SIGTSTP\n);raise(SIGTSTP);printf(Signal SIGTSTP is ignored\n);return 0;
}
编译和执行步骤
Testing SIGTSTP
Signal SIGTSTP is ignored
到目前为止我们已经观察到我们有一个信号处理程序来处理一个信号。我们可以有一个处理程序来处理多个信号吗?答案是肯定的。让我们考虑一个程序。
以下程序执行以下操作-
步骤1 - 注册一个处理程序(handleSignals)以捕获或处理信号SIGINT(CTRL C)或SIGQUIT(CTRL \)
步骤2 - 如果用户生成信号SIGQUIT(通过终止命令或使用CTRL \的键盘控制)则处理程序仅将消息打印为返回。
步骤3 - 如果用户首次生成信号SIGINT(通过kill命令或使用CTRL C的键盘控制)则它将修改该信号以从下一次执行默认操作(使用SIG_DFL)。
步骤4 - 如果用户第二次生成信号SIGINT它将执行默认操作即终止程序。
/* Filename: sigHandler.c */
#includestdio.h
#includeunistd.h
#includesignal.hvoid handleSignals(int signum);int main(void) {void (*sigHandlerInterrupt)(int);void (*sigHandlerQuit)(int);void (*sigHandlerReturn)(int);sigHandlerInterrupt sigHandlerQuit handleSignals;sigHandlerReturn signal(SIGINT, sigHandlerInterrupt);if (sigHandlerReturn SIG_ERR) {perror(signal error: );return 1;}sigHandlerReturn signal(SIGQUIT, sigHandlerQuit);if (sigHandlerReturn SIG_ERR) {perror(signal error: );return 1;}while (1) {printf(\nTo terminate this program, perform the following:\n);printf(1. Open another terminal\n);printf(2. Issue command: kill %d or issue CTRLC 2 times (second time it terminates)\n, getpid());sleep(10);}return 0;
}void handleSignals(int signum) {switch(signum) {case SIGINT:printf(\nYou pressed CTRLC\n);printf(Now reverting SIGINT signal to default action\n);signal(SIGINT, SIG_DFL);break;case SIGQUIT:printf(\nYou pressed CTRL\\\n);break;default:printf(\nReceived signal number %d\n, signum);break;}return;
}
编译和执行步骤
To terminate this program, perform the following:
1. Open another terminal
2. Issue command: kill 74 or issue CTRLC 2 times (second time it terminates)
^C
You pressed CTRLC
Now reverting SIGINT signal to default actionTo terminate this program, perform the following:
1. Open another terminal
2. Issue command: kill 74 or issue CTRLC 2 times (second time it terminates)
^\You pressed CTRL\
To terminate this program, perform the following:
1. Open another terminal
2. Issue command: kill 120
Terminated
另一个终端
kill 71
第二种方法
我们知道要处理信号我们有两个系统调用即signal()或sigaction()。到目前为止我们已经看到了signal()系统调用现在是时候进行sigaction()系统调用了。让我们修改上述程序以使用sigaction()如下执行-
/* Filename: sigHandlerSigAction.c */
#includestdio.h
#includeunistd.h
#includesignal.hvoid handleSignals(int signum);int main(void) {void (*sigHandlerReturn)(int);struct sigaction mysigaction;mysigaction.sa_handler handleSignals;sigemptyset(mysigaction.sa_mask);mysigaction.sa_flags 0;sigaction(SIGINT, mysigaction, NULL);if (mysigaction.sa_handler SIG_ERR) {perror(signal error: );return 1;}mysigaction.sa_handler handleSignals;sigemptyset(mysigaction.sa_mask);mysigaction.sa_flags 0;sigaction(SIGQUIT, mysigaction, NULL);if (mysigaction.sa_handler SIG_ERR) {perror(signal error: );return 1;}while (-1) {printf(\nTo terminate this program, perform either of the following:\n);printf(1. Open another terminal and issue command: kill %d\n, getpid());printf(2. Issue CTRLC 2 times (second time it terminates)\n);sleep(10);}return 0;
}void handleSignals(int signum) {switch(signum) {case SIGINT:printf(\nYou have entered CTRLC\n);printf(Now reverting SIGINT signal to perform default action\n);signal(SIGINT, SIG_DFL);break;case SIGQUIT:printf(\nYou have entered CTRL\\\n);break;default:printf(\nReceived signal number %d\n, signum);break;}return;
}
让我们看看编译和执行进程。在执行进程中让我们两次查看CTRL C问题其余检查/方式(如上所述)也可以尝试该程序。
编译和执行步骤
To terminate this program, perform either of the following:
1. Open another terminal and issue command: kill 3199
2. Issue CTRLC 2 times (second time it terminates)
^C
You have entered CTRLC
Now reverting SIGINT signal to perform default action
To terminate this program, perform either of the following:
1. Open another terminal and issue command: kill 3199
2. Issue CTRLC 2 times (second time it terminates)
^C 进程 - 信号(Signals) - 无涯教程网无涯教程网提供信号是对进程的通知指示事件的发生。信号也称为软件中断无法预知其发生因此也称...https://www.learnfk.com/process/inter-process-communication-signals.html