📄 function.html
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN"><HTML><HEAD> <TITLE>与信号相关的函数</TITLE> <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=gb2312-80"> <META NAME="COPYRIGHT" CONTENT="魏永明"> <META NAME="AUTHOR" CONTENT="魏永明"> <STYLE> <!-- H1 { color: #ffff00 } H2 { color: #ffff00 } H3 { color: #ff00ff } H4 { color: #ffff00 } TD P { color: #b880b8 } LI { color: #ffffff } P { color: #00ffff } PRE { color: #ffffff; font-family: "fixed" } A:link { color: #00b8ff } A:visited { color: #ff3366 } --> </STYLE></HEAD><BODY TEXT="#ffff00" LINK="#00b8ff" VLINK="#ff3366" BACKGROUND="images/velvet.jpg"><A HREF="reliable.html"><IMG SRC="prev.gif" ALT="Previous"></A><A HREF="thread.html"><IMG SRC="next.gif" ALT="Next"></A><A HREF="index.html"><IMG SRC="toc.gif" ALT="Contents"></A><H1 ALIGN=CENTER>6.4 与信号相关的函数<BR><BR></H1><UL> <LI>kill 和 raise</LI> <LI>alarm 和 pause</LI> <LI>abort, system 和 sleep</LI></UL><H3>6.4.1 kill 和 raise</H3><UL> <LI>kill: 向其它进程发送信号</LI> <LI>raise: 向当前进程发送信号</LI><PRE>=============================================================================== #include <sys/types.h> #include <signal.h> int kill (pid_t pid, int sig); int raise (int sig);-------------------------------------------------------------------------------kill 的 pid 参数的四种条件: * pid > 0: 信号发送到 PID 为 pid 的进程. * pid == 0: 信号发送到与发送进程处于同一进程组的进程. * pid < -1: 信号发送到进程组 ID 等于 -pid 的所有进程. * pid == -1: POSIX 未指定. Linux 发送到进程表中所有的进程, 除第一个进程之外. * sig == 0 时, 不会发送任何信号, 但仍然执行错误检查, 因此可用来检查是否有 向指定进程发送信号的许可.===============================================================================</PRE> <LI>raise 等价于 kill (getpid (), sig)</LI></UL><H3>6.4.2 alarm 和 pause</H3><UL> <LI>alarm 可设置定时器. 定时器到期时, 将产生 SIGALRM 信号</LI> <LI>setitimer 是另一个设置间隔定时器的函数, 更加灵活</LI><PRE>=============================================================================== #include <unistd.h> unsigned int alarm (unsigned int seconds);------------------------------------------------------------------------------- #include <sys/time.h> int getitimer (int which, struct itimerval *value); int setitimer (int which, const struct itimerval *value, struct itimerval *ovalue);------------------------------------------------------------------------------- * alarm 的返回值为先前尚未过期的定时器所剩余的时间. * alarm 和 setitimer 使用同一个定时器, 因此会互相影响. * setitimer 定时精度要比 alarm 高, 同时可以按照进程的执行时间 (用户态时间, 核心态时间, 或两者) 进行计时.-------------------------------------------------------------------------------EXAMPLE: /* MiniGUI 的定时器 */ void sig_handler (int v) { int sem_value; timer_counter++; // alert desktop DskMsgs.dwState |= 0x01; sem_getvalue (&DskMsgs.wait, &sem_value); if (sem_value == 0) sem_post(&DskMsgs.wait); } BOOL InitTimer () { struct itimerval timerv; struct sigaction siga; siga.sa_handler = sig_handler; siga.sa_flags = 0; memset (&siga.sa_mask, 0, sizeof (sigset_t)); sigaction (SIGALRM, &siga, &old_alarm_handler); timerv.it_interval.tv_sec = 0; timerv.it_interval.tv_usec = 10000; timerv.it_value = timerv.it_interval; if (setitimer (ITIMER_REAL, &timerv, &old_timer)) { fprintf(stderr, "TIMER: setitimer call failed!\n"); perror("setitimer"); return FALSE; } timer_counter = 0; return TRUE; } BOOL TerminateTimer () { int i; if (setitimer (ITIMER_REAL, &old_timer, 0) == -1) { fprintf( stderr, "Timer: setitimer call failed!\n"); perror("setitimer"); return 0; } if (sigaction (SIGALRM, &old_alarm_handler, NULL) == -1) { fprintf( stderr, "Timer: sigaction call failed!\n"); perror("sigaction"); return 0; } for (i=0; i < MAX_TIMERS; i++) { if (timerstr[i] != NULL) free ( timerstr[i] ); timerstr[i] = NULL; } return 1; }===============================================================================</PRE> <LI>pause 暂停调用进程并等待信号</LI><PRE>=============================================================================== #include <unistd.h> int pause (void);===============================================================================</PRE></UL><H3>6.4.3 abort, system 和 sleep</H3><UL> <LI>abort 函数向进程发送 SIGABRT 信号, 从而可导致程序非正常终止</LI><PRE>=============================================================================== #include <stdlib.h> void abort (void);------------------------------------------------------------------------------- * 如果捕获 SIGABRT 信号, 且信号处理器不返回, 则 abort 不能终止进程. * abort 终止进程时, 所有打开的流均会被刷新并关闭. * 如果 SIGABRT 被阻塞或忽略, abort 将覆盖这种设置.===============================================================================</PRE> <LI>system: 执行系统命令</LI><PRE>=============================================================================== #include <stdlib.h> int system (const char * string);------------------------------------------------------------------------------- * 在执行命令的过程中, SIGCHLD 被阻塞, 而 SIGINT 和 SIGQUIT 被忽略.-------------------------------------------------------------------------------EXAMPLE: /* POSIX.2 implementation of system function */ #include <sys/types.h> #include <sys/wait.h> #include <errno.h> #include <signal.h> #include <unistd.h> int system (const char *cmdstring) /* with appropriate signal handling */ { pid_t pid; int status; struct sigaction ignore, saveintr, savequit; sigset_t childmask, savemask; if (cmdstring == NULL) return (1); /* always a command processor with UNIX */ 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 (&childmask); /* now block SIGCHLD */ sigaddset (&childmask, SIGCHLD); if (sigprocmask (SIG_BLOCK, &childmask, &savemask) < 0) return (-1); if ( (pid = fork ()) < 0) { status = -1; /* probably out of processes */ } else if (pid == 0) { /* child */ /* restore previous signal actions & rest signal mask */ sigaction (SIGINT, &saveintr, NULL); sigaction (SIGQUIT, &savequit, NULL); sigprocmask (SIG_SETMASK, &savemask, NULL); execl ("/bin/sh", "sh", "-c", cmdstring, (char *)0); _exit (127); /* exec error */ } else { /* parent */ while (waitpid (pid, &status, 0) < 0) if (errno != EINTR) { status = -1; /* errno other than EINTR form waitpid() */ break; } } /* restore previous signal actions & reset signal mask */ 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); }===============================================================================</PRE> <LI>sleep: 休眠指定的秒数</LI><PRE>=============================================================================== #include <unistd.h> unsigned int sleep (unsigned int seconds);------------------------------------------------------------------------------- * 经过指定的时间之后, sleep 返回. * 在这之前, 如果接收到信号, 则 sleep 返回剩余的秒数.--------------------------------------------------------------------------------------------------------------------------------------------------------------EXAMPLE: /* POSIX.2 implementation of sleep function */ #include <sys/types.h> #include <stddef.h> #include <signal.h> #include <unistd.h> static void sig_alrm (void) { return; /* nothing to do, just returning wakes up sigsuspend() */ } unsigned int sleep (unsigned int nsecs) { struct sigaction newact, oldact; sigset_t newmask, oldmask, suspmask; unsigned int unslept; newact.sa_handler = sig_alrm; sigemptyset (&newact.sa_mask); newact.sa_flags = 0; sigaction (SIGALRM, &newact, &oldact); /* set our handler, save previous information */ sigemptyset (&newmask); sigaddset (&newmask, SIGALRM); /* block SIGALRM and save current signal mask */ sigprocmask (SIG_BLOCK, &newmask, &oldmask); alarm (nsecs); suspmask = oldmask; sigdelset (&suspmask, SIGALRM); /* make sure SIGALRM isn't blocked */ sigsuspend (&suspmask); /* wait for any signal to be caught */ /* some signal has been caught, SIGALRM is now blocked */ unslept = alarm (0); sigaction (SIGALRM, &oldact, NULL); /* reset previous action */ sigprocmask (SIG_SETMASK, &oldmask, NULL); return (unslept); }===============================================================================</PRE></UL><P><BR><BR></P><P ALIGN=CENTER><IMG SRC="images/striped.gif" NAME="Ruler" ALIGN=BOTTOM WIDTH=532 HEIGHT=13 BORDER=0></P><P><BR><BR></P><A HREF="reliable.html"><IMG SRC="prev.gif" ALT="Previous"></A><A HREF="thread.html"><IMG SRC="next.gif" ALT="Next"></A><A HREF="index.html"><IMG SRC="toc.gif" ALT="Contents"></A></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -