linux poll 作用,Linux中poll机制的理解

首先分析下应用程序的执行过程:

int main(int argc, char **argv)

{

int fd;

unsigned char key_val;

int ret;

struct pollfd fds[1];

fd = open("/dev/buttons", O_RDWR);

if (fd < 0)

{

printf("can't open!

");

}

fds[0].fd     = fd;

fds[0].events = POLLIN;

while (1)

{

ret = poll(fds, 1, 5000); ///本处的应用程序在while(1)中持续的调用poll函数

if (ret == 0)

{

printf("time out

");

}

else

{

read(fd, &key_val, 1);

printf("key_val = 0x%x

", key_val);

}

}

return 0;

}

/**********************************************************************************************************************************/

应用程序中在while(1)循环中持续的调用poll函数,poll函数根据file->op 结构体在其中寻找成员函数poll ->通过调用成员函数poll

由用户空间进入系统内核,内核自动调用sys_poll();函数,接下来介绍内核调用函数顺序过程,缩进代表子函数调用:

app:poll

kernel: sys_poll

do_sys_poll(......, timeout_jffies);

poll_initwait(&table);  设置一个变量 table->qproc=_pollwait  以后会用到

init_poll_funcptr(&pwq->pt,__pollwait); //就是将table->qproc=__pollwait

do_poll(nfds,head,&table,timeout);

for(;;)//死循环 也就是说 根本不给外层用户空间while(1)循环调用的机会,加上后面的休眠机制,所以对系统CPU资源的消耗会比较小

{

if(do_pollfd(pfd,pt))// 这个地方函数分析:实际执行 mask= file->f_op->poll(file,pwait);   return mask;

{

count++;     //所以 如果 驱动程序中的 poll的返回值非零,那么可以让count++:否则count=0;

pt= NULL;

}

}

//break的条件来了

if(count|| !*timeout||signal_pending(current))

break;

//休眠

_timeout= schedule_timeout(_timeout);

到这里 poll机制的内核调用部分框架结束;

/********************************再将内核驱动程序中的poll函数贴出来*********************************************/

static unsigned forth_drv_poll(struct file *file, poll_table *wait)

{

unsigned int mask = 0;

poll_wait(file, &button_waitq, wait); // 不会立即休眠

if (ev_press)

mask |= POLLIN | POLLRDNORM;

return mask;

}

内核调用 sys_poll以后,会调用驱动中的poll函数

然后poll函数主要做两件事情:

1 执行poll_wait(file,&button_waitq,wait); 函数

分析:p->qproc(filp, wait_address, p);  而这个 q->proc 就是之前设置的__pollwait

所以执行_pollwait();函数 作用是将当前进程挂载到运行队列中

2  查询一下(ev_press)这个标志位 检测是否发生了中断,如果是的,那么MASK返回非零值,

内核中就可以break出这个死循环,进而处理别的

如果当时没有发生中断 MASK值为零,那么会进入休眠状态 _timeout*****();这个函数

此时它仍然可以被唤醒 两种情况 一种计时时间到,自动跳出死循环,来到外部应用程序死循环中;第二次执行上述过程

第二种,发生中断情况,此时进入中断处理函数,将ev_press的值变为1. 同时唤醒进程(唤醒以后从哪里开始执行不是很了解!!!)

唤醒进程以后,驱动程序继续运行,继续判断if(ev_press)是否为真,此时poll函数返回非零值  应用程序获取到非零值,执行相应的操作

现在的理解是 _pollwait();函数就是将当前执行代码加载到可执行队列中,也就意味着一旦唤醒 从此处继续执行!!!!

希望会对没有接触过操作系统学linux的同学一点理解poll的思路!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值