概述
本文来自个人博客:https://dunkwan.cn
文章目录
- 函数`system`
- 函数`sleep`、`nanosleep`和`clock_nanosleep`
函数system
由于system
执行的命令可能是交互式的命令,因为system
的调用者在程序执行时放弃了控制,等待该执行程序的结束,所以system
的调用者就不应接收SIGINT
和SIGQUIT
这两个终端产生的信号。
测试示例1:
system
实现版本一,为考虑忽略SIGINT
和SIGQUIT
信号。
#include "../../include/apue.h"
#include <sys/wait.h>
#include <unistd.h>
int system(const char *);
static void sig_int(int);
static void sig_chld(int);
int main(void)
{
if(signal(SIGINT, sig_int) == SIG_ERR)
err_sys("signal(SIGINT) error");
if(signal(SIGCHLD, sig_chld) == SIG_ERR)
err_sys("signal(SIGCHLD) error");
if(system("/bin/ed") < 0)
err_sys("system() error");
return 0;
}
int system(const char *cmdstring) /* version without signal handling */
{
pid_t pid;
int status;
if (cmdstring == NULL)
return(1); /* always a command processor with UNIX */
if ((pid = fork()) < 0) {
status = -1; /* probably out of processes */
} else if (pid == 0) { /* child */
execl("/bin/sh", "sh", "-c", cmdstring, (char *)0);
_exit(127); /* execl error */
} else { /* parent */
while (waitpid(pid, &status, 0) < 0) {
if (errno != EINTR) {
status = -1; /* error other than EINTR from waitpid() */
break;
}
}
}
return(status);
}
static void sig_int(int signo)
{
printf("caught SIGINTn");
}
static void sig_chld(int signo)
{
printf("caught SIGCHLDn");
}
结果如下:
测试示例2:
system
函数版本2,此版本进行了所要求的信号的处理。
#include "../../include/apue.h"
#include <sys/wait.h>
static void sig_int(int);
static void sig_chld(int);
int system(const char *);
int main()
{
if(signal(SIGINT, sig_int) == SIG_ERR)
err_sys("signal(SIGINT) error");
if(signal(SIGCHLD, sig_chld) == SIG_ERR)
err_sys("signal(SIGCHLD) error");
if(system("/bin/ed") < 0)
err_sys("system() error");
return 0;
}
static void sig_int(int signo)
{
printf("caught SIGINTn");
}
static void sig_chld(int signo)
{
printf("caught SIGCHLDn");
}
int system(const char *cmdstring) /* with appropriate signal handling */
{
pid_t pid;
int status;
struct sigaction ignore, saveintr, savequit;
sigset_t chldmask, savemask;
if(cmdstring == NULL)
return (1);
ignore.sa_handler = SIG_IGN; /* ignore SIGINT and SIGQUIT */
sigemptyset(&ignore.sa_mask);
ignore.sa_flags = 0;
if(sigaction(SIGINT, &ignore, &saveintr) < 0)
return (-1);
if(sigaction(SIGQUIT, &ignore, &savequit) < 0)
return (-1);
sigemptyset(&chldmask);
sigaddset(&chldmask, SIGCHLD);
if(sigprocmask(SIG_BLOCK, &chldmask, &savemask) < 0)
return (-1);
if((pid = fork()) < 0){
status = -1;
}else if(pid == 0){
sigaction(SIGINT, &saveintr, NULL);
sigaction(SIGQUIT, &savequit, NULL);
sigprocmask(SIG_SETMASK, &savemask, NULL);
execl("/bin/sh", "sh", "-c", cmdstring, (char *)0);
_exit(127);
}else{
while(waitpid(pid, &status, 0) < 0)
if(errno != EINTR){
status = -1;
break;
}
}
if(sigaction(SIGINT, &saveintr, NULL) < 0)
return (-1);
if(sigaction(SIGQUIT, &savequit, NULL) < 0)
return (-1);
if(sigprocmask(SIG_SETMASK, &savemask, NULL) < 0)
return (-1);
return (status);
}
结果如下:
函数sleep
、nanosleep
和clock_nanosleep
sleep
函数定义如下:
#include <unistd.h>
unsigned int sleep(unsigned int seconds);
返回值:0或未休眠完的秒数。
此函数使调用进程被挂起直到满足下面两个条件之一。
- 已经过了
seconds
所指定的墙上时钟时间。- 调用进程捕捉到一个信号并从信号处理程序返回。
以下是一个POSIX.1的sleep
函数的实现。
#include "apue.h"
static void sig_alrm(int signo){
/* nothing to do, just returned wakes up sigsuspend() */
}
unsigned int sleep(unsigned int seconds)
{
struct sigaction newact, oldact;
sigset_t newmask, oldmask, suspmask;
unsigned int unslept;
/* set our handler, save previous information */
newact.sa_handler = sig_alrm;
sigemptyset(&newact.sa_mask);
newact.sa_flags = 0;
sigaction(SIGALRM, &newact, &oldact);
/* block SIGALRM and save current signal mask */
sigemptyset(&newmask);
sigaddset(&newmask, SIGALRM);
sigprocmask(SIG_BLOCK, &newmask, &oldmask);
alarm(seconds);
suspmask = oldmask;
/* make sure SIGALRM isn't blocked */
sigdelset(&suspmask, SIGALRM);
/* wait for any signal to be caught */
sigsuspend(&suspmask);
/* some signal has been caught, SIGALRM is now blocked */
unslept = alarm(0);
/* reset previous action */
sigaction(SIGALRM, &oldact, NULL);
/* reset signal mask, which unblocks SIGALRM */
sigprocmask(SIG_SETMASK, &oldmask, NULL);
return (unslept);
nanosleep
函数与sleep
函数类似,但提供了纳秒级的精度。
#include <time.h>
int nanosleep(const struct timespec *reqtp, struct timespec *remtp);
返回值:若休眠到要求的时间,返回0;若出错,返回-1。
reqtp
参数用秒和纳秒来指定需要休眠的时间长度。如果某个信号中断了休眠间隔,进程并没有终止,remtp
参数指向的timespec
结构就会被设置为未休眠完的时间长度。如果对未休眠完的时间并不感兴趣,可以设置为NULL
。
随着多个系统时钟的引入,需要使用相对于特定时钟的延迟时间来挂起调用线程。clock_nanosleep
函数提供了这种功能。
#include <time.h>
int clock_nanosleep(clockid_t clock_id, int flags, const struct timespec *reqtp, struct timespec *remtp);
返回值:若休眠要求的时间,返回0;若出错,返回错误码。
clock_id
参数指定了计算延迟时间基于的时钟。flags
参数用于控制延迟是相对的还是绝对的。flags
为0时表示休眠时间是相对的,如果flags
为TIMER_ABSTIME
,表示休眠时间是绝对的。其他的参数reqtp
和remtp
,与nanosleep
函数中相同。但是,使用绝对时间时,remtp
参数未使用,因为不必要。在时钟到达指定的绝对时间值以前,可以为其他的clock_nanosleep
调用复用reqtp
参数相同的值。
`
clock_id
参数指定了计算延迟时间基于的时钟。flags
参数用于控制延迟是相对的还是绝对的。flags
为0时表示休眠时间是相对的,如果flags
为TIMER_ABSTIME
,表示休眠时间是绝对的。其他的参数reqtp
和remtp
,与nanosleep
函数中相同。但是,使用绝对时间时,remtp
参数未使用,因为不必要。在时钟到达指定的绝对时间值以前,可以为其他的clock_nanosleep
调用复用reqtp
参数相同的值。
注意: 除了出错返回,调用clock_nanosleep(CLOCK_REALTIME, 0, reqtp, remtp);
和调用 nanosleep(reqtp, remtp);
效果相同。使用相对休眠时间的问题是对于那些对休眠精度有要求的应用来说,相对休眠时间会导致实际休眠时间比要求的长,当采用绝对时间时,这样却可以很好的改善精度。
最后
以上就是开心网络为你收集整理的信号之函数system、sleep、nanosleep以及clock_nanosleep的全部内容,希望文章能够帮你解决信号之函数system、sleep、nanosleep以及clock_nanosleep所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复