《unix网络环境编程》 中20-7 的示例理解。
1 #include "unp.h" 2 3 static void recvfrom_alarm(int); 4 5 void 6 dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen) 7 { 8 int n; 9 const int on = 1; 10 char sendline[MAXLINE], recvline[MAXLINE + 1]; 11 fd_set rset; 12 sigset_t sigset_alrm, sigset_empty; 13 socklen_t len; 14 struct sockaddr *preply_addr; 15 16 preply_addr = Malloc(servlen); 17 18 Setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)); 19 20 FD_ZERO(&rset); 21 22 Sigemptyset(&sigset_empty); 23 Sigemptyset(&sigset_alrm); 24 Sigaddset(&sigset_alrm, SIGALRM); 25 26 Signal(SIGALRM, recvfrom_alarm); 27 28 while (Fgets(sendline, MAXLINE, fp) != NULL) { 29 Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen); 30 31 Sigprocmask(SIG_BLOCK, &sigset_alrm, NULL); 32 alarm(5); 33 for ( ; ; ) { 34 FD_SET(sockfd, &rset); 35 n = pselect(sockfd+1, &rset, NULL, NULL, NULL, &sigset_empty); 36 if (n < 0) { 37 if (errno == EINTR) 38 break; 39 else 40 err_sys("pselect error"); 41 } else if (n != 1) 42 err_sys("pselect error: returned %d", n); 43 44 len = servlen; 45 n = Recvfrom(sockfd, recvline, MAXLINE, 0, preply_addr, &len); 46 recvline[n] = 0; /* null terminate */ 47 printf("from %s: %s", 48 Sock_ntop_host(preply_addr, len), recvline); 49 } 50 } 51 free(preply_addr); 52 } 53 54 static void 55 recvfrom_alarm(int signo) 56 { 57 return; /* just interrupt the recvfrom() */ 58 }
#include <stdio.h> #include <unistd.h> #include <signal.h> static void handle_signal(int signo) { printf("come here\n"); return ; } int main() { sigset_t signal_usr1, signal_old; sigemptyset(&signal_usr1); sigaddset(&signal_usr1, SIGUSR1); sigprocmask(SIG_BLOCK, &signal_usr1, &signal_old); signal(SIGUSR1, handle_signal); sleep(30); sigprocmask(SIG_SETMASK, &signal_old, NULL); return 0; }
将上边这个程序编译好之后,运行,运行期间向这个进程发送 SIGUSR1 信号,最后发现仍然后有 “come here” 输出。
说明:
sigprocmask 虽然将 SIGUSR1 屏蔽掉了,但是如果在屏蔽期间收到了 SIGUSR1 信号,解除屏蔽后会统一处理该信号。
那么此时返回来看上边那个pselect 的例子就会发现,代码的意思是确保 SIGALRM 信号只在pselect 中处理。
原文:https://www.cnblogs.com/rivsidn/p/10636706.html