一,前言
动手写linux驱动(3)--Apple的学习笔记已经写了一个阻塞,现在做一个非阻塞驱动,添加poll。
工程6是用select和poll,多路复用文件数量大,IO频繁的话用epoll,epoll最大的好处是不会随着fd数量增多而降低效率。只要epoll为什么好那么多我之前介绍过,网上有很多资料,原因比如用边沿触发,只通知一次,IO内存copy方式为mmap映射等。
工程6源码上传在gitee上https://gitee.com/applecai/linux-driver-study
二,遇到的问题
- 刚刚写完select监控读和写的app后,top查看性能期望为0,结果为100%,查了下原因,因为我driver在无数据可读时会阻塞,也支持内容非满则阻塞。我用select同时监控读和写,由于先ioctl清空数据,所以一直可以写,导致一直在while中运行,没有机会sleep,才会看到性能100%。是个bug,对于我的fifo设计的driver,select只能监控同时监控一个,APP代码改成仅监控读即可。
- timeout.tv_sec需要放在while循环中,FD_ZERO和FD_SET最好也放while中。否则只有第一次timeout设置有效,之后就不设置延迟监控了。
三,测试效果
select的timeout为5s,在5s内没有io写入动作,则休眠,作用top查看性能基本为0.
# ./applepaper6 /dev/applepaper6
[ 519.383704] applepaper is set to zero
start
timeout
start
timeout
start
^C
# ./applepaper6 /dev/applepaper6 &
# [ 533.386380] applepaper is set to zero
start
top
Mem: 20684K used, 482772K free, 44K shrd, 0K buff, 1964K cached
CPU: 0% usr 0% sys 0% nic 100% idle 0% io 0% irq 0% sirq
Load average: 0.00 0.00 0.00 1/51 128
PID PPID USER STAT VSZ %VSZ %CPU COMMAND
128 109 root R 1500 0% 0% top
109 1 root S 1536 0% 0% -sh
1 0 root S 1500 0% 0% init
80 1 root S 1492 0% 0% /sbin/syslogd -n
84 1 root S 1488 0% 0% /sbin/klogd -n
127 109 root S 688 0% 0% ./applepaper6 /dev/applepaper6
49 2 root IW 0 0% 0% [kworker/0:3-pm]
60 2 root IW< 0 0% 0% [kworker/u3:2-xp]
48 2 root IW 0 0% 0% [kworker/0:2-eve]
120 2 root IW< 0 0% 0% [kworker/u3:3-xp]
64 2 root IW 0 0% 0% [kworker/u2:5-rp]
9 2 root SW 0 0% 0% [ksoftirqd/0]
10 2 root IW 0 0% 0% [rcu_sched]
61 2 root IW 0 0% 0% [kworker/u2:2-rp]
7 2 root IW 0 0% 0% [kworker/u2:0-rp]
59 2 root IW< 0 0% 0% [kworker/u3:1-xp]
45 2 root IW 0 0% 0% [kworker/u2:1-rp]
63 2 root IW 0 0% 0% [kworker/u2:4-rp]
119 2 root IW< 0 0% 0% [kworker/u3:0-xp]
timeout 2 root IW 0 0% 0% [kworker/u2:6-rp]
start
Mem: 20668K used, 482788K free, 44K shrd, 0K buff, 1964K cached
CPU: 0% usr 0% sys 0% nic 99% idle 0% io 0% irq 0% sirq
Load average: 0.00 0.00 0.00 1/51 128
PID PPID USER STAT VSZ %VSZ %CPU COMMAND
109 1 root S 1536 0% 0% -sh
1 0 root S 1500 0% 0% init
128 109 root R 1500 0% 0% top
80 1 root S 1492 0% 0% /sbin/syslogd -n
84 1 root S 1488 0% 0% /sbin/klogd -n
127 109 root S 688 0% 0% ./applepaper6 /dev/applepaper6
49 2 root IW 0 0% 0% [kworker/0:3-eve]
60 2 root IW< 0 0% 0% [kworker/u3:2-xp]
48 2 root IW 0 0% 0% [kworker/0:2-eve]
120 2 root IW< 0 0% 0% [kworker/u3:3-xp]
64 2 root IW 0 0% 0% [kworker/u2:5-rp]
9 2 root SW 0 0% 0% [ksoftirqd/0]
10 2 root IW 0 0% 0% [rcu_sched]
61 2 root IW 0 0% 0% [kworker/u2:2-rp]
7 2 root IW 0 0% 0% [kworker/u2:0-rp]
59 2 root IW< 0 0% 0% [kworker/u3:1-xp]
45 2 root IW 0 0% 0% [kworker/u2:1-rp]
63 2 root IW 0 0% 0% [kworker/u2:4-fl]
119 2 root IW< 0 0% 0% [kworker/u3:0-xp]
timeout 2 root IW 0 0% 0% [kworker/u2:6-rp]
start
检查read效果,APP在后台运行,echo输入good job后可以通过select识别到并且打印出来。
# ./applepaper6 /dev/applepaper7 &
# [ 74.832696] applepaper is set to zero
# echo "timeout
good job!"timeout
# echo "good job!" >/dev/applepaper7timeout
[ 89.955800] written 10 bytes,current_len:10
[ 89.960137] read 1 bytes,current_len:9
# [ 89.966461] read 1 bytes,current_len:8
[ 89.970293] read 1 bytes,current_len:7
[ 89.974786] read 1 bytes,current_len:6
[ 89.978589] read 1 bytes,current_len:5
[ 89.982377] read 1 bytes,current_len:4
[ 89.986819] read 1 bytes,current_len:3
[ 89.990620] read 1 bytes,current_len:2
[ 89.995005] read 1 bytes,current_len:1
[ 89.998802] read 1 bytes,current_len:0
good job!
# timeout
top
Mem: 20800K used, 482656K free, 44K shrd, 0K buff, 1956K cached
CPU: 9% usr 0% sys 0% nic 90% idle 0% io 0% irq 0% sirq
Load average: 0.03 0.02 0.00 1/52 113
PID PPID USER STAT VSZ %VSZ %CPU COMMAND
113 109 root R 1500 0% 9% top
109 1 root S 1536 0% 0% -sh
1 0 root S 1500 0% 0% init
80 1 root S 1492 0% 0% /sbin/syslogd -n
84 1 root S 1488 0% 0% /sbin/klogd -n
112 109 root S 688 0% 0% ./applepaper6 /dev/applepaper7
60 2 root IW< 0 0% 0% [kworker/u3:2-xp]
49 2 root IW 0 0% 0% [kworker/0:3-nfs]
48 2 root IW 0 0% 0% [kworker/0:2-eve]
15 2 root IW 0 0% 0% [kworker/0:1-rcu]
41 2 root IW< 0 0% 0% [kworker/u3:0-xp]
65 2 root IW 0 0% 0% [kworker/u2:6-rp]
10 2 root IW 0 0% 0% [rcu_sched]
64 2 root IW 0 0% 0% [kworker/u2:5-rp]
9 2 root SW 0 0% 0% [ksoftirqd/0]
13 2 root SW 0 0% 0% [kdevtmpfs]
45 2 root IW 0 0% 0% [kworker/u2:1-rp]
7 2 root IW 0 0% 0% [kworker/u2:0-rp]
59 2 root IW< 0 0% 0% [kworker/u3:1-xp]
timeout 2 root IW< 0 0% 0% [netns]