您的位置:首页 > 运维架构 > Linux

基于视频压缩的实时监控系统-A2:linux中最优秀的多路复用机制Epoll

2017-04-09 10:12 751 查看
Epoll 支持管道,FIFO,套接字,POSIX消息队列,终端,设备等,但就是不支持普通文件!!

1、epoll函数详解:

1.1创建监听池:

int epoll_creat(int size);

int epoll_create1(int flags);

创建epoll监听池,第一个函数从2.6.8版本之后不在有入口参数size。

入口参数:第二个函数的入口参数是创建标志,一般我们让他等于0,此时两个函数的功能一模一样。

返回值:所创建监听池的fd

1.2:添加要监听的事件

int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);

入口参数:

epfd:监听池的fd

op:要进行的操作例如注册事件,可能的取值EPOLL_CTL_ADD 注册、EPOLL_CTL_MOD 修 改、EPOLL_CTL_DEL 删除

fd:需要监听文件的fd

epoll_event:指向epoll_event的指针; 

如果调用成功返回0,不成功返回-1

struct epoll_event {
uint32_t     events;      /* Epoll events */
epoll_data_t data;        /* User data variable */
};


其中events取值:EPOLLIN 可读、EPOLLOUT    可写

data:可以写文件的fd


返回值:成功:0            失败:-1

1.3:等待事件的发生

int epoll_wait(int epfd, struct epoll_event *events,int maxevents, int timeout);

入口参数:

epfd:监听池fd

events:事件数组,来存储已经发生的事件

maxevents:允许事件的最大数目

timeout:超时时间(当timeout=-1的时候,会一直等)

返回值:有事件发生:发生事件的个数、没有事件发生:0、错误:-1  

2、epoll函数示例:test.c利用epoll机制监听两个FIFO、client.c向两个fifo中写入,以满足可读的要求

 

test.c:

#include <stdio.h>
#include <sys/epoll.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
int main()
{
int fd1,fd2;
//创建FIFO
int efd;
struct epoll_event Events;
struct epoll_event *Es;
int n;
int i;
mkfifo("/tmp/fifo1",0666);
mkfifo("/tmp/fifo2",0666);

fd1 = open("/tmp/fifo1",O_RDWR);
fd2 = open("/tmp/fifo2",O_RDWR);

//创建监听池

efd = epoll_create1(0);

//构造监听事件,加入监听池

Events.events = EPOLLIN | EPOLLET;   //设置为读事件,并设置为边沿触发
Events.data.fd = fd1;
epoll_ctl(efd,EPOLL_CTL_ADD,fd1,&Events);

Events.events = EPOLLIN | EPOLLET;   //设置为读事件,并设置为边沿触发
Events.data.fd = fd2;
epoll_ctl(efd,EPOLL_CTL_ADD,fd2,&Events);
//为Es数组分配内存

Es = calloc(100,sizeof(Events));

n = epoll_wait(efd,Es,100,-1);
for(i = 0;i < n;i++)
{
if(Es[i].events & EPOLLIN)
{
printf("file %d can be read\n",Es[i].data.fd);
}
if(Es[i].events & EPOLLOUT)
{

}
}
free(Es);
close(fd1);
close(fd2);
}


client.c

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>

int main(int argc,char *argv[])
{
int fd1,fd2;
char c[5] = "Hello";
fd1 = open("/tmp/fifo1",O_RDWR);
fd2 = open("/tmp/fifo2",O_RDWR);

if(*argv[1] == '1')
write(fd1,c,5);

if(*argv[1] == '2')
write(fd2,c,5);

close(fd1);
close(fd2);
}


编译之后,先在一个终端中运行test,在另一个终端中运行client

./client 1:向FIFO1中写入

./client 2:向FIFO2中写入
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: