本文探讨一个《Unix/Linux编程实践教程》P219出现的bug,在Linux上bounce_async.c程序代码运行失败。
Unix有两个异步输入(asynchronous input)系统。
一种方法是当输入就绪时发送信号,另一个系统当输入被读入时发送信号。UCB(BSD)中通过设置文件描述块(file descriptor)的O_ASYNC位来实现第一种方法。
第二种方法是POSIX标准,它调用aio_read。
实验第一种方法时,我采用书中代码,就是一个弹球程序,发现了其不能在键入"Q"正常退出
#include <stdio.h> #include <stdlib.h> #include <curses.h> #include <signal.h> #include <fcntl.h> #define MESSAGE "hello" #define BLANK " " int row =10; int col =0; int dir =1; int delay =200; int done =0; int main() { void on_alarm(int); void on_input(int); void enable_kbd_signals(); sigset_t * set; set=(sigset_t*)malloc(sizeof(set)); sigemptyset(set); sigaddset(set,SIGIO); sigprocmask(SIG_UNBLOCK, set, NULL); initscr(); crmode(); noecho(); clear(); enable_kbd_signals(); signal(SIGIO,(on_input)); enable_kbd_signals(); signal(SIGALRM,on_alarm); set_ticker(delay); move(row,col); addstr(MESSAGE); while(!done) { pause(); } endwin(); } void on_input(int signum) { int c = getch(); if(c=='Q'||c==EOF) done=1; else if(c==' ') dir=-dir; } void on_alarm(int signum) { signal(SIGALRM,on_alarm); mvaddstr(row,col,BLANK); col+=dir; mvaddstr(row,col,MESSAGE); refresh(); if(dir==-1&&col<=0) dir=1; else if(dir==1&&col+strlen(MESSAGE)>=COLS) dir=-1; } void enable_kbd_signals() { int fd_flags; fcntl(0,F_SETOWN,getpid()); fd_flags=fcntl(0,F_GETFL); fcntl(0,F_SETFL,(fd_flags|O_ASYNC)); }
遇到这个问题后,我很困惑,于是邮件问了作者Bruce Molay,没想到他神速的回复了我的邮件!兴奋异常!
下面我贴出的回复,这不算侵权吧,@Bruce Molay~
他的英文还是很好懂的。真是很大家风范,大家以后遇到问题也可以多联系作者,It is so cool!!
Linux和Unix有一定的区别,在学习Unix的过程中,我们经常使用Linux做实验,我们需要注意其区别!