Linux-视频监控系统(2)-Epoll的介绍及使用
2017-07-11 15:48
507 查看
1、什么是Epoll
1.1阻塞型IO和多路复用
假如说现在有一个进程需要对设备进行读写,但是这个过程一般需要时间不能马上完成,为了节约CPU资源,这时候一般进程都采取阻塞的方法,把自己挂起,等有设备已经完成操作了再自行其他程序。这种等待方法叫做阻塞型IO假如一个进程需要同时对4个设备文件进行监控,比如说需要监控打印机有没有打印完成、键盘有没有输入数据,这个过程就叫做多路复用。
那么哪个函数可以既可以实现阻塞型IO又可以实现多路复用呢?
select函数,下面是select函数的使用复习
1、初始化需要操作的文件集合FD_ZERO(&set)
2、把文件描述符一个一个的加到集合中,FD_SET
3、调用select,开始监控,如果没有文件符合会阻塞在这里,直到超时或者有文件满足要求,然后继续运行
4、遍历每个文件,找到哪个文件发生了变化
那么select存在哪些缺点呢?在最后遍历文件的过程中,是极其耗费时间的过程如果文件太多,那这对资源更是一个极大的浪费。
所以这里引入Epoll函数,它同样可以实现阻塞和多路复用,同时不需要遍历所有文件就可以知道是哪个文件发生了什么变化,比如说文件里面已经有数据了可以唤醒应用程序来读,比如说应用程序要求写入的数据已经写入了,可以继续做下面的事情了。。而且Epoll可以监控的文件是没有上限的!
2、怎么使用Epoll
但是要注意Epoll支持管道,FIFO,套接字,POSIX消息队列,终端,设备等,但就是不支持普通文件!!!比如说文件文件,MP3文件等普通文件它都不支持。Epoll的使用分为3个环节。
epoll_create/epoll_create1 (创建epoll监听池)
epoll_ctl (添加要监听的事件)
epoll_wait (等待事件的发生)
epoll_create
在Linux下man一下这个函数:epoll_create是创建一个监听池,在2.8之前的内核版本中它表明监听文件的数量,在2.8以后的版本中没有任何意义。
epoll_create1有一个flags的参数,当参数为0时和epoll_create函数是一样的同时这个函数的返回值就是监听池的描述符。
epoll_ctl
添加要监听的事件,比如说添加A文件可读、添加A文件可写,当事件发生时可以立马知道是哪个事件发生了什么操作,所以不再需要遍历所有文件了。它的原型是:
int epoll_ctl(int enfd, int op, int fd, struct epoll event *event)
第一个参数是监听池的fd,第二个参数是操作的类型比如加入事件、取出事件、删除事件、修改事件等,第三个是事件所对应文件的fd,第四个是事件类型,
struct epoll_event {
__uint32_t events
epoll data data;
};
第一个是事件的类型比如读写,EPOLLIN、EPOLLOUT。
返回值是int类型,成功返回0,失败返回-1
epoll_wait
等待事件的发生,它的原型是int epoll_wait (int epfd, struct epoll_event *events,
int maxevent,int timeout)
第一个参数是epfd,第二个参数存放发生事件的指针,当事件发生后会把对应文件的操作事件写入这个数组。第四个是最大事件的数组,第五个是超时时间。
那么在摄像头监控系统中存在哪些需要等待的事情呢?
1、摄像头存在一帧新的图像(可读)
2、socket可以发送数据(可写)
3、socket可以接收数据(可读)
因此在我们的监控系统中非常有必要引入Epoll框架程序
下面写一个简单的程序来使用Epoll:
#include<stdio.h>
#include<stdlib.h>
#include<fcntl.h>
#include<sys/epoll.h>
int main()
{
int fd1,fd2;
int ep_fd;
struct epoll_event event;
struct epoll_event *events;
int n,i;
char c;
mkfifo("/tmp/fifo1",0666);
mkfifo("/tmp/fifo2",0666);
fd1 = open("/tmp/fifo1",O_RDONLY);
fd2 = open("/tmp/fifo2",O_RDONLY);
ep_fd = epoll_create1(0);
event.events = EPOLLIN | EPOLLET;
event.data.fd = fd1;
epoll_ctl(ep_fd, EPOLL_CTL_ADD, fd1, &event);
event.events = EPOLLIN | EPOLLET;
event.data.fd = fd2;
epoll_ctl(ep_fd, EPOLL_CTL_ADD, fd2, &event);
events = calloc(100, sizeof(event));
n = epoll_wait(ep_fd, events, 100, -1);
for(i=0; i<n; i++)
{
if(events[i].events & EPOLLIN)
{
read(events[i].data.fd, &c, 1);
printf("file %d read %c!\n",events[i].data.fd,c);
}
if(events[i].events & EPOLLOUT)
{
}
}
close(fd1);
close(fd2);
close(ep_fd);
return 0;
}
然后编写一个fifo读写的程序:
#include<stdio.h>
#include<stdlib.h>
#include<fcntl.h>
#include<sys/epoll.h>
int main()
{
int fd;
char c = 'x';
fd = open("/tmp/fifo1", O_WRONLY);
write(fd, &c, 1);
close(fd);
return 0;
}
同样写出对另一个fifo2文件的读写程序。
然后编译后依次运行这几个文件,如果写入数据后ep文件打印出对于的字符即编写成功。
相关文章推荐
- Linux-视频监控系统(3)-Epoll框架的实现
- 基于视频压缩的实时监控系统-A2:linux中最优秀的多路复用机制Epoll
- 使用linux系统性能监控工具KSysguard监控远端主机介绍
- linux系统监控——nmon介绍与使用
- linux系统监控——nmon介绍与使用
- Linux 查看磁盘分区、文件系统、磁盘的使用情况相关的命令和工具介绍
- Linux 查看磁盘分区、文件系统、使用情况的命令和相关工具介绍
- 简要介绍如何配置与使用 Linux 网络系统的多播IP
- Linux嵌入式视频直播监控系统
- 使用 inotify 监控 Linux 文件系统事件
- Linux 查看磁盘分区、文件系统、使用情况的命令和相关工具介绍
- 使用Inotify 监控Linux 文件系统事件
- Linux 查看磁盘分区、文件系统、磁盘的使用情况相关的命令和工具介绍
- 转 Linux 查看磁盘分区、文件系统、使用情况的命令和相关工具介绍
- Linux 查看磁盘分区、文件系统、使用情况的命令和相关工具介绍
- Linux 查看磁盘分区、文件系统、使用情况的命令和相关工具介绍
- Linux中系统整体性能监控工具详细介绍
- 视频监控系统介绍 基础知识
- Linux 查看磁盘分区、文件系统、使用情况的命令和相关工具介绍
- ARM-Linux下用Servfox和Spcaview 建立嵌入式视频监控系统