linux sigrof信号,linux信号与高级IO

66b52468c121889b900d4956032f1009.png

8种机械键盘轴体对比

本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选?

1、Linux中的信号

信号相关的定义都在这里usr/include/i386-linux-gnu/bits/signum.h

什么是信号

1、信号是内容受限的一种异步通信机制

(1)信号的目的:用来通信

(2)信号是异步的(对比硬件中断)

(3)信号本质上是int型数字编号(事先定义好的)

2、信号由谁发出

(1)用户在终端按下按键

(2)硬件异常后由操作系统内核发出信号

(3)用户使用kill命令向其他进程发出信号

(4)某种软件条件满足后也会发出信号,如alarm闹钟时间到会产生SIGALARM信号,向一个读端已经关闭的管道write时会产生SIGPIPE信号

3、信号由谁处理、如何处理

(1)忽略信号

(2)捕获信号(信号绑定了一个函数)

(3)默认处理(当前进程没有明显的管这个信号,默认:忽略或终止进程)

常见信号介绍信号数字功能SIGINT2Ctrl+C时OS送给前台进程组中每个进程

SIGABRT6调用abort函数,进程异常终止

SIGPOLLSIGIO8指示一个异步IO事件,在高级IO中提及

SIGKILL9杀死进程的终极办法

SIGSEGV11无效存储访问时OS发出该信号

SIGPIPE13涉及管道和socket

SIGALARM14涉及alarm函数的实现

SIGTERM15kill命令发送的OS默认终止信号

SIGCHLD17子进程终止或停止时OS向其父进程发此信号

SIGUSR110用户自定义信号,作用和意义由应用自己定义

SIGUSR212用户自定义信号,作用和意义由应用自己定义

进程对信号的处理

signal函数介绍

用signal函数处理SIGINT信号

(1)默认处理

(2)忽略处理

(3)捕获处理

细节:

(1)signal函数绑定一个捕获函数后信号发生后会自动执行绑定的捕获函数,并且把信号编号作为传参传给捕获函数

(2)signal的返回值在出错时为SIG_ERR,绑定成功时返回旧的捕获函数

signal函数的优点和缺点

(1)优点:简单好用,捕获信号常用

(2)缺点:无法简单直接得知之前设置的对信号的处理方法

sigaction函数介绍

(1)2个都是API,但是sigaction比signal更具有可移植性

(2)用法关键是2个sigaction指针

sigaction比signal好的一点:sigaction可以一次得到设置新捕获函数和获取旧的捕获函数(其实还可以单独设置新的捕获或者单独只获取旧的捕获函数),而signal函数不能单独获取旧的捕获函数而必须在设置新的捕获函数的同时才获取旧的捕获函数。

#include

#include

#include

typedef void (*sighandler_t)(int);

void func(int sig)

{

if (SIGINT != sig)

return;

printf("func for signal: %d.n", sig);

}

int main(void)

{

sighandler_t ret = (sighandler_t)-2;

//signal(SIGINT, func);

//signal(SIGINT, SIG_DFL);// 指定信号SIGINT为默认处理

ret = signal(SIGINT, SIG_IGN);// 指定信号SIGINT为忽略处理

if (SIG_ERR == ret)

{

perror("signal:");

exit(-1);

}

printf("before while(1)n");

while(1);

printf("after while(1)n");

return 0;

}

alarm和pause函数

1、alarm函数

(1)内核以API形式提供的闹钟

(2)编程实践

2、pause函数

(1)内核挂起

(2)代码实践

pause函数的作用就是让当前进程暂停运行,交出CPU给其他进程去执行。当当前进程进入pause状态后当前进程会表现为“卡住、阻塞住”,要退出pause状态当前进程需要被信号唤醒。

2、高级IO

非阻塞IO

1、阻塞与非阻塞

之前也学过这个概念,阻塞就是会被阻止住,程序不会再继续往下执行,知道这个阻塞函数执行完才可以。

非阻塞就是不用等待,直接往下执行。

2、为什么有阻塞式

(1)常见的阻塞:wait、pause、sleep等函数;read或write某些文件时

3、非阻塞

如何实现非阻塞IO访问:O_NONBLOCK和fcntl

阻塞式IO的困境

1、程序中读取键盘

2、程序中读取鼠标

3、程序中同时读取键盘和鼠标

#include

#include

#include

#include

#include

#include

int main(void)

{

// 读取鼠标

int fd = -1;

char buf[200];

fd = open("/dev/input/mouse1", O_RDONLY);

if (fd < 0)

{

perror("open:");

return -1;

}

memset(buf, 0, sizeof(buf));

printf("before 鼠标 read.n");

read(fd, buf, 50);

printf("鼠标读出的内容是:[%s].n", buf);

// 读键盘

memset(buf, 0, sizeof(buf));

printf("before 键盘 read.n");

read(0, buf, 5);

printf("键盘读出的内容是:[%s].n", buf);

return 0;

}

/*

int main(void)

{

// 读取鼠标

int fd = -1;

char buf[200];

fd = open("/dev/input/mouse1", O_RDONLY);

if (fd < 0)

{

perror("open:");

return -1;

}

memset(buf, 0, sizeof(buf));

printf("before read.n");

read(fd, buf, 50);

printf("读出的内容是:[%s].n", buf);

return 0;

}

*/

/*

int main(void)

{

// 读取键盘

// 键盘就是标准输入,stdin

char buf[100];

memset(buf, 0, sizeof(buf));

printf("before read.n");

read(0, buf, 5);

printf("读出的内容是:[%s].n", buf);

return 0;

}

*/

并发式IO的解决方案

1、非阻塞式IO

2、多路复用IO

3、异步通知(异步IO)

因为上面这样不能很好的解决同时读取鼠标和键盘的问题,所以我们有了一下的解决方案。

IO多路复用原理

1、何为IO多路复用

(1)IO multiplexing(IO多路复用的英文)

(2)用在什么地方?多路非阻塞式IO。

(3)select和poll

(4)外部阻塞式,内部非阻塞式自动轮询多路阻塞式IO

2、select函数

3、poll函数

select函数和poll函数其实差不多,只是因为unix当时出现了两个分支,写出来的两个东西,poll函数好像是由加州伯克利分校写出来的。

3.6.5.1、用select函数实现同时读取键盘鼠标

#include

#include

#include

#include

#include

#include

#include

#include

int main(void)

{

// 读取鼠标

int fd = -1, ret = -1;

char buf[200];

fd_set myset;

struct timeval tm;

fd = open("/dev/input/mouse1", O_RDONLY);

if (fd < 0)

{

perror("open:");

return -1;

}

// 当前有2个fd,一共是fd一个是0

// 处理myset

FD_ZERO(&myset);

FD_SET(fd, &myset);

FD_SET(0, &myset);

tm.tv_sec = 10;

tm.tv_usec = 0;

ret = select(fd+1, &myset, NULL, NULL, &tm);

if (ret < 0)

{

perror("select: ");

return -1;

}

else if (ret == 0)

{

printf("超时了n");

}

else

{

// 等到了一路IO,然后去监测到底是哪个IO到了,处理之

if (FD_ISSET(0, &myset))

{

// 这里处理键盘

memset(buf, 0, sizeof(buf));

read(0, buf, 5);

printf("键盘读出的内容是:[%s].n", buf);

}

if (FD_ISSET(fd, &myset))

{

// 这里处理鼠标

memset(buf, 0, sizeof(buf));

read(fd, buf, 50);

printf("鼠标读出的内容是:[%s].n", buf);

}

}

return 0;

}

3.6.5.2、用poll函数实现同时读取键盘鼠标

#include

#include

#include

#include

#include

#include

#include

int main(void)

{

// 读取鼠标

int fd = -1, ret = -1;

char buf[200];

struct pollfd myfds[2] = {0};

fd = open("/dev/input/mouse1", O_RDONLY);

if (fd < 0)

{

perror("open:");

return -1;

}

// 初始化我们的pollfd

myfds[0].fd = 0;// 键盘

myfds[0].events = POLLIN;// 等待读操作

myfds[1].fd = fd;// 鼠标

myfds[1].events = POLLIN;// 等待读操作

ret = poll(myfds, fd+1, 10000);

if (ret < 0)

{

perror("poll: ");

return -1;

}

else if (ret == 0)

{

printf("超时了n");

}

else

{

// 等到了一路IO,然后去监测到底是哪个IO到了,处理之

if (myfds[0].events == myfds[0].revents)

{

// 这里处理键盘

memset(buf, 0, sizeof(buf));

read(0, buf, 5);

printf("键盘读出的内容是:[%s].n", buf);

}

if (myfds[1].events == myfds[1].revents)

{

// 这里处理鼠标

memset(buf, 0, sizeof(buf));

read(fd, buf, 50);

printf("鼠标读出的内容是:[%s].n", buf);

}

}

return 0;

}

异步IO

1、何为异步IO

(1)几乎可以认为:异步IO就是操作系统用软件实现的一套中断响应系统。类似于硬件的中断,只不过这是软件的

(2)异步IO的工作方法是:我们当前进程注册一个异步IO事件(使用signal注册一个信号SIGIO的处理函数),然后当前进程可以正常处理自己的事情,当异步事件发生后当前进程会收到一个SIGIO信号从而执行绑定的处理函数去处理这个异步事件。

2、涉及的函数:

(1)fcntl(F_GETFL、F_SETFL、O_ASYNC、F_SETOWN)

(2)signal或者sigaction(SIGIO)

#include

#include

#include

#include

#include

#include

#include

int mousefd = -1;

// 绑定到SIGIO信号,在函数内处理异步通知事件

void func(int sig)

{

char buf[200] = {0};

if (sig != SIGIO)

return;

read(mousefd, buf, 50);

printf("鼠标读出的内容是:[%s].n", buf);

}

int main(void)

{

// 读取鼠标

char buf[200];

int flag = -1;

mousefd = open("/dev/input/mouse1", O_RDONLY);

if (mousefd < 0)

{

perror("open:");

return -1;

}

// 把鼠标的文件描述符设置为可以接受异步IO

flag = fcntl(mousefd, F_GETFL);

flag |= O_ASYNC;

fcntl(mousefd, F_SETFL, flag);

// 把异步IO事件的接收进程设置为当前进程

fcntl(mousefd, F_SETOWN, getpid());

// 注册当前进程的SIGIO信号捕获函数

signal(SIGIO, func);

// 读键盘

while (1)

{

memset(buf, 0, sizeof(buf));

//printf("before 键盘 read.n");read(0, buf, 5);

printf("键盘读出的内容是:[%s].n", buf);

}

return 0;

}

存储映射IO

1、mmap函数

2、LCD显示和IPC之共享内存

3、存储映射IO的特点

(1)共享而不是复制,减少内存操作

(2)处理大文件时效率高,小文件不划算

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值