当一个进程睡眠,它这样做以期望个别条件在之后会成真.任何睡眠的进程必须在它再度睡醒时检测来确保它在等待的条件真正为真.最常用的函数为:
wait_event_interruptible(queue,condition)
其中queue是要用的等待队列头.注意它是”通过值”传递的.条件是一个被这个宏在睡眠前后所求值的任意的布尔表达式;直至条件求值为真值,进程继续睡眠。
睡眠唤起的函数为:
voidwake_up_interruptible(wait_queue_head_t*queue);
通过视频少将到的代码可以看出,使用了wait_event_interruptible()后linux按键驱动,测试程序使用while循环读取按钮状态也不会抢占99%的CPU资源了,进程会在条件不满足时步入睡眠,晓得按钮按下后,由wake_up_interruptible()唤起。
同步的另一种方式是使用select、poll机制。它是一种非阻塞I/O的应用程序经常使用的机制。poll,select和epoll本质上有相同的功能:每位容许一个进程来决定它是否可读或则写一个或多个文件而不阻塞。file_operations结构体中poll的原型为:
unsignedint(*poll)(structfile*filp,poll_table*wait); 函数主要的作用就是为用户空间的poll、select提供一个系统调用。最后返回一个mask。
视频中poll的代码很简单linux按键驱动,主要使用了poll_wait()函数。
voidpoll_wait(structfile*,wait_queue_head_t*,poll_table*);
用户空间在调用poll前设置了structpollfdfds;通过对fd和events参数的指定,致使在fd发生了events指定的条件后唤起。最后判定ev_press是否按下linux应用程序linux手机软件,并返回位网段。应用程序通过返回值是否为0判定是否须要读取按钮状态。
视频还讲了一种异步的方式读取键盘值。file_operations结构体中fasync原型为:
int(*fasync)(intfd,structfile*filp,inton)
驱动程序须要在该函数中通过fasync_helper()实现。fasync_helper被调用来从相关的进程列表中添加或除去入口项,当FASYNC标志因一个打开文件而改变。它的所有参数不仅最后一个,都被提供给fasync方式而且被直接传递。当数据抵达时kill_fasync被拿来通知相关的进程。它的参数是被传递的讯号(往往是SIGIO)和band,这几乎都是POLL_IN。
中断触发后通过kill_fasync()来唤起进程。应用程序中signal设置讯号,fcntl设置FASYNC标志位。