=============================================================================== #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 时, 不会发送任何信号, 但仍然执行错误检查, 因此可用来检查是否有 向指定进程发送信号的许可. ===============================================================================
=============================================================================== #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; } ===============================================================================
=============================================================================== #include <unistd.h> int pause (void); ===============================================================================
=============================================================================== #include <stdlib.h> void abort (void); ------------------------------------------------------------------------------- * 如果捕获 SIGABRT 信号, 且信号处理器不返回, 则 abort 不能终止进程. * abort 终止进程时, 所有打开的流均会被刷新并关闭. * 如果 SIGABRT 被阻塞或忽略, abort 将覆盖这种设置. ===============================================================================
=============================================================================== #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); } ===============================================================================
=============================================================================== #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); } ===============================================================================