ch04:訊號處理

來源:互聯網
上載者:User
 

第四講 訊號處理訊號是處理序間通訊的最簡單形式訊號的生命週期簡單訊號#include <signal.h>void *signal(int signum, void *handler);SIG_IGN, SIG_DFL, SIGKILL, SIGSTOP可靠訊號 (sigset_t)訊號和系統調用 Linux訊號系統api       發送訊號       int tkill(pid_t pid, int signum);       int raise(int signum);       使用sigset_t       #include <signal.h>       int sigemptyset(sigset_t *set);       int sigfillset(sigset_t *set); // 將當前全部的有效訊號添加到set中       int sigaddset(sigset_t *set, int signum);       int sigdelset(sigset_t *set, int signum);       int sigismember(const sigset_t *set, int signum);       EINVAL              #include<signal.h>       int sigaction(int signum, struct sigaction *act, struct sigaction *oact);       struct sigaction{              __sighandler_t sa_handler;              sigset_t sa_mask;              int sa_flags;}void handler(int signum);SA_NOCLDSTOP, SA_NODEFER, SA_RESETHAND, SA_RESTART while( *src )       *dest++ = *src++;int sigprocmask(int what, const sigset_t *set, sigset_t *oldset);SIG_BLOCK, SIG_UNBLOCK, SIG_SETMASKsigprocmask(SIG_BLOCK, NULL, &currentSet); sigset_t hup;sigemptyset(&hup);sigaddset(&hup, SIGHUP);sigprocmask(SIG_BLOCK, &hup, NULL);while(*src)       *dest++ = *src++;sigprocmask(SIG_UNBLOCK, &hup,NULL);       int sigpending(sigset_t *set); int pause(void);int sigsuspend(const sigset_t *mask);errno = EINTR      訊號SIGABRT, SIGALM, SIGBUS, SIGCHLD, SIGCONT,SIGFPE, SIGHUP, SIGILL, SIGINT, SIGIO, SIGKILL, SIGPIPE, SIGPROF, SIGPWR, SIGQUIT, SIGSEGV, SIGSTOP, SIGSYS, SIGTERM, SIGTRAP, SIGTSTP, SIGTTIN, SIGTTOU, SIGURG, SIGUSR1, SIGUSR2, SIGVTALRM, SIGWINCH, SIGXCPU, SIGXFSZ 編寫訊號處理常式重新開啟記錄檔例#include <error.h>#include <signal.h>#include <stdio.h>#include <string.h>#include <unistd.h> volatile int reopenLog = 0; void logstring(int logfd, char *str){       write(logfd,str,strlen(str));} void hupHandler(int signum){       reopenLog = 1;} int main() {       int done = 0;       struct sigaction sa;       int rc;       int logfd;              logfd = STDOUT_FILENO;              memset(&sa, 0, sizeof(sa));       sa.sa_handler = hupHandler;              if (sigaction(SIGHUP, &sa, NULL))          {              perror("sigaction");       }        while (!done)       {              rc = sleep(5);                            if (rc)              {                     if (reopenLog)                     {                            logstring(logfd,"*reopening log files at sig hup request/n");                            reopenLog = 0;                     }                     else                     {                            logstring(logfd,"*sleep interrupted by unkown signal/n");                            done = 1;                     }              }              else              {                     logstring(logfd, "periodic message/n");              }       }       return 0;}即時訊號SIGRTMIN, SIGRTMAX例#define _GNU_SOURCE 1 #include <sys/signal.h>#include <stdlib.h>#include <stdio.h>#include <string.h>#include <unistd.h> int nextSig = 0;int sigOrder[10]; void handler(int signo){       sigOrder[nextSig++] = signo;} int main(){       sigset_t mask;       sigset_t oldmask;       struct sigaction act;       int i;        sigemptyset(&mask);       sigaddset(&mask, SIGRTMIN);       sigaddset(&mask, SIGRTMIN + 1);       sigaddset(&mask, SIGUSR1);        act.sa_handler = handler;       act.sa_mask = mask;       act.sa_flags = 0;        sigaction(SIGRTMIN, &act, NULL);       sigaction(SIGRTMIN + 1, &act, NULL);       sigaction(SIGUSR1, &act ,NULL);        sigprocmask(SIG_BLOCK, &mask, &oldmask);       raise(SIGRTMIN + 1);       raise(SIGRTMIN);       raise(SIGRTMIN);       raise(SIGRTMIN + 1);       raise(SIGRTMIN);       raise(SIGUSR1);       raise(SIGUSR1);              sigprocmask(SIG_SETMASK, &oldmask, NULL);        printf("signals received:/n");        for (i = 0; i < nextSig; i++)       {              if (sigOrder[i] < SIGRTMIN)              {                     printf("/t%s/n",strsignal(sigOrder[i]));              }              else               {                     printf("/tSIGRTIM + %d/n",sigOrder[i] - SIGRTMIN);              }            }            return 0;} 擷取訊號資訊得到訊號上下文void handler(int signum, siginfo_t *siginfo, void *context);SA_SIGINFO#include <signal.h>struct sigaction{       union{       __sighandler_t sa_handler;       __sigaction_t sa_sigaction;}sigset_t sa_mask;unsigned long sa_flags;}       #define sa_handler __sigactin_handler.sa_handler       #define sa_sigaction __sigaction_handler.sa_sigaction       Si_signo si_code: SI_USER, SI_QUEUE, SI_TKILL, SI_KERNEL       SIGSEGV SEGV_MAPER               SEGV_ACCERRSIGBUS    BUS_ADDRALN           BUS_ADDERR           BUS_OBJERRSIGCHLD CLD_EXITED                 CLD_KILLED                 CLD_STOPPED       例子#include <sys/signal.h>#include <stdlib.h>#include <stdio.h>#include <unistd.h> #ifndef SI_TKILL#define SI_TKILL -6#endif void handler(int signo, siginfo_t *info, void *f){       static int count = 0;       printf("caught signal sent by ");              switch(info->si_code)       {              case SI_USER:                     printf("kill()/n");                     break;              case SI_QUEUE:                     printf("sigqueue()/n");                     break;              case SI_TKILL:                     printf("tkill() or raise()/n");                     break;              case CLD_EXITED:                     printf("kernel telling us child exited/n");                     exit(0);       }              if (++count == 4)              _exit(1);} int main(){       struct sigaction act;       union sigval val;              pid_t pid = getpid();              val.sival_int = 1234;              act.sa_sigaction = handler;       sigemptyset(&act.sa_mask);       act.sa_flags = SA_SIGINFO;       sigaction(SIGCHLD, &act, NULL);        kill(pid, SIGCHLD);       sigqueue(pid, SIGCHLD, val);       raise(SIGCHLD);        if (!fork())       {              _exit(0);       }       sleep(60);       return 0;} #include <sys/signal.h>#include <stdlib.h>#include <stdio.h> void handler(int signo, siginfo_t *info, void *f){       printf("caught");              if (info->si_signo == SIGSEGV)       {              printf("segv accessing %p", info->si_addr);       }        if (info->si_code == SEGV_MAPERR)       {              printf("segv_maperr");       }              printf("/n");       _exit(1);} int main() {       struct sigaction act;    act.sa_sigaction = handler;       sigemptyset(&act.sa_mask);       act.sa_flags = SA_SIGINFO;       sigaction(SIGSEGV, &act, NULL);       *((int*)NULL) = 1;       return 0;} 使用訊號發送資料#include <signal.h>void *sigqueue(pid_t pid ,int signum, const union sigval value);union sigval{       int sival_int;       void *sival_ptr;}例#include <sys/signal.h>#include <stdlib.h>#include <stdio.h>#include <string.h>#include <unistd.h> void handler(int signo, siginfo_t *si ,void *context){       printf("%d/n", si->si_value.sival_int);} int main(){       sigset_t mask;       sigset_t oldmask;       struct sigaction act;       int me = getpid();       union sigval val;              act.sa_sigaction = handler;       act.sa_mask = mask;       act.sa_flags = SA_SIGINFO;       sigaction(SIGRTMIN, &act, NULL);              sigemptyset(&mask);       sigaddset(&mask, SIGRTMIN);              sigprocmask(SIG_BLOCK, &mask, &oldmask);       val.sival_int = 1;       sigqueue(we, SIGRTMIN, val);       val.sival_int++;       sigqueue(we, SIGRTMIN, val);       val.sival_int++;       sigqueue(we, SIGRTMIN, val);       sigprocmask(SIG_SETMASK, &oldmask, NULL);        return 0;}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.