pselect 函数

  《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 中处理

猜你喜欢

转载自www.cnblogs.com/rivsidn/p/10636706.html
今日推荐