屏蔽信号的多路选择I/O

前边提到了多路I/O的方法,这一章屏蔽信号的多路选择与之前的多路I/O一致,只是增加了屏蔽信号的作用。多路选择I/O中我们使用的是select函数,屏蔽信号的多路选择I/O使用的是pselect函数,与之前的函数相比,增加了一个参数可以用来屏蔽信号。具体函数如下所示:

int pselect(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset, const struct timespec *timeout, const sigset_t *sigmask);

头文件: #include <sys/select.h>

参数说明:前4个参数与select函数的参数相同,分别表示最大的文件描述符和关心的文件中状态。

第5个参数表示等待时间,所不同的是timespec结构所能表示的最小精度是纳秒,旧的结构体中所能表示的最小精度是微妙数。

pselect函数最后一个参数可以用来屏蔽信号,在pselect函数返回后,再将屏蔽的信号恢复,并且所有的操作都是原子的。

返回值:超时返回0,出错返回-1,成功返回描述字的个数。

下面用两个程序的对比来说明select函数与pselect函数的区别。

第一个程序使用select函数,程序中人为的制造了一个造成函数阻塞的条件。该程序在阻塞的时候会被信号中断。

#include <stdio.h>
#include <sys/select.h>
#include <stdlib.h>
#include <signal.h>
/* SIGUSR1的信号处理函数 */
void sigusr1_handler(int signo)
{
       printf("catch SIGUSR1\n"); /* 接收SIGUSR1信号,打印接收信息 */
}
int main()
{
       int rdy; /* 准备好的设备数 */
       /* 注册信号处理函数,如果捕捉到信号则输出提示信息 */
       if(signal(SIGUSR1, sigusr1_handler) == SIG_ERR){
              perror("can’t set handler for SIGUSR1");
              exit(1);
       }
       /* 不关心所有的设备准备状态,所以检查设备的最大文件描述符的值也不再有意义。
       * 等待时间结构为NULL,表示将等待时间设置为无限等待
       */
       rdy = select(1, NULL, NULL, NULL, NULL);
       /* 因为是无限等待,所以绝对不应该执行到这里,输出提示信息 */
       printf("should never be here\n");
       return 0;
}

第二个程序使用pselect函数,程序中人为的制造了一个造成函数阻塞的条件。该程序在阻塞的时候不会被信号中断。

#include <stdio.h>
#include <sys/select.h>
#include <stdlib.h>
#include <signal.h>
/* SIGUSR1的信号处理函数 */
void sigusr1_handler(int signo)
{
       printf("catch SIGUSR1\n"); /* 接收SIGUSR1信号,打印接收信息 */
}
int main()
{
       int rdy;                                /* 准备好的设备数 */
       sigset_t set;                         /* 信号集 */
         /* 注册信号处理函数,如果捕捉到信号则输出提示信息 */
       if(signal(SIGUSR1, sigusr1_handler) == SIG_ERR){
              perror("can’t set handler for SIGUSR1");
              exit(1);
       }
       sigfillset(&set); /* 设置信号集,屏蔽所有的信号,包括SIGKILL和SIGSTOP */
       /* 不关心所有的设备准备状态,所以检查设备的最大文件描述符的值也不再有意义。
       * 等待时间结构为NULL,表示将等待时间设置为无限等待
        */
       rdy = pselect(1, NULL, NULL, NULL, NULL, &set);
       /* 因为是无限等待,所以绝对不应该执行到这里,输出提示信息 */
       printf("should never be here\n");
       return 0;
}

在调试的时候用kill命令向进程发送SIGUSR1信号,观察输出结果,通过两个程序运行的对比可以清楚的理解pselect函数和select函数的区别。

时间: 2024-10-12 07:12:41

屏蔽信号的多路选择I/O的相关文章

多路选择I/O

多路选择I/O提供另一种处理I/O的方法,相比于传统的I/O方法,这种方法更好,更具有效率.多路选择是一种充分利用系统时间的典型. 1.多路选择I/O的概念 当用户需要从网络设备上读数据时,会发生的读操作一般分为两步. (1)等待数据准备好,等待数据的到达,并且将其复制到内核的缓冲区,该缓冲区在系统态. (2)复制数据,将数据从内核缓冲区中复制到用户指定的缓冲区中. 一般的读操作形式为: Int nbytes = read(sfd, buf, MAX); 如果需要的数据没有准备好,例如,数据尚未

在浏览器屏蔽右键、文本选择、文本拖动、复制等操作

事件 说明  oncontextmenu   在用户点击鼠标右键打开上下文菜单时触发   onselectstart  在用户开始选取元素时触发  onselectstart  在用户开始拖动元素时触发  oncopy  在用户拷贝元素内容时触发 当事件被触发,使用 return false; 语句能够禁用默认的事件行为. <html> <head> <title>hello</title> <script type="text/javasc

channler多路选择和超时控制

一.多渠道的选择和超时控制select{}1.多需渠道选择: 当任何一个case不处于阻塞情况会输出case内的逻辑, 当所有的都没有准备好都处于阻塞情况的话select出现defalt就会执行defalut内代码. select { case ret := <-retCh1: fmt.Println(ret) case ret := <--retCh2: fmt.Println(ret) default: t.Errorf("No one returned") }2.超时

信号的屏蔽,信号集

1.信号集 POSIX标准定义了数据类型sigset_t #include <signal.h> int sigemptyset(sigset_t *set); 初始化一个信号集,使其不包括任何信号 int sigfillset(sigset_t *set); 用来初始化一个信号集,使其包括所有信号 int sigaddset(sigset_t *set, int signum); 用来向set指定的信号集中添加由signum指定的信号 int sigdelset(sigset_t *set,

linux 信号屏蔽

<span style="font-size:18px;">#include <sys/types.h> #include <unistd.h> #include <signal.h> #include <stdio.h> #include <stdlib.h> #include <errno.h> /* sigemptyset(&newmask);//获取空屏蔽信号集 sigfillset(&

Linux学习笔记(10)-信号

所谓信号(singal),在我的理解来说,其实和单片机开发中的中断差不多,但是它并非是由系统硬件所提供的,而是软件操作系统的支持的一种提醒机制. 收到信号之后的处理方法,一般由三种: (1)第一种是类似于中断处理函数,对于要处理的信号,进程指定某个处理函数. (2)第二种是忽略某个信号,不做任何处理. (3)第三种是使用系统默认的处理方式,比如Ctrl+c的终止当前进程. Linux中常用的信号有30多种,每个信号都以关键字SIG开头,比如异常终止的信号,名叫SIGABRT. 在头文件<Sing

转 linux 之信号

APUE讲信号真是生涩,着实读者无趣,如是找一篇总结比较好的博客. 原文http://blog.chinaunix.net/uid-24774106-id-4061386.html Linux编程,信号是一个让人爱恨交加又不得不提的一个领域.最近我集中学习了Linux的signal相关的内容,分享出来,也为防止自己忘记.     信号的本质是异步.异步一这个词,听着高端大气上档次,又让人云山雾绕,其则不然.其实我们想想,我们这个世界是异步的,每个人干事儿,并不总是 A->B->C->D这

linux下 signal信号机制的透彻分析与各种实例讲解

转自:http://blog.sina.com.cn/s/blog_636a55070101vs2d.html 转自:http://blog.csdn.net/tiany524/article/details/17048069 首先感谢上述两位博主的详细讲解. 虽然内容有点长,但是分析的很全面,各种实例应用基本都考虑到了. 本文将从以下几个方面来阐述信号: (1)信号的基本知识 (2)信号生命周期与处理过程分析 (3) 基本的信号处理函数 (4) 保护临界区不被中断 (5) 信号的继承与执行 (

linux_api之信号

本片索引: 1.引言 2.信号 3.程序启动 4.signal函数 5.系统调用的中断和系统调用的重启(了解) 6.可再入与不可再入函数(了解) 7.kill函数和raise函数 8.alarm函数和pause函数 9.信号的发送.接收和处理的过程 10.信号集设置函数和sigprocmask函数 11.sigpending函数 12.sigaction函数 13.sigsuspend函数 14.abort函数 15.sleep函数           1.引言 信号是一种软件中断,与之相对应的