目录
问题:
getch()阻塞获取键盘按键输入, 怎么操作才能不影响小鸟下落和管道移动?
getch如果阻塞,下面的程序都是无法执行。通过信号机制方式实现。
在Linux中,软中断信号(signal,简称为信号)是在软件层次上对中断的一种模拟,用来通知进程发生了异步事件。内核可以因为内部事件而给进程发送信号,通知进程发生了某个事件。
信号响应的方式:
1.忽略信号,即对信号不做任何处理;
2.捕捉信号,即信号发生时执行用户自定义的信号处理函数。
3.执行缺省操作,Linux对每种信号都规定了默认操作。
信号的检测与处理流程图

- #include
- #include
-
- typedef void (*sighandler_t)(int);
- sighandler_t signal(int signum, sighandler_t handler);
成功时返回原先的信号处理函数,失败时返回SIG_ERR
signum:指明了所要处理的信号类型
handler:描述了与信号关联的动作
SIG_DFL代表缺省方式; SIG_IGN 代表忽略信号;
指定的信号处理函数代表捕捉方式
示例
- // 头文件省略
- void handler (int signo) {
-
- printf(“HELLO!\n”);
- }
-
- int main() {
- signal(SIGINT, handler);
- while ( 1 ) ;
- return 0;
- }
- struct itimerval {
- struct timeval it_interval; /* 计时器重新启动的间歇值 */
- struct timeval it_value; /* 计时器安装后首次启动的初 }; 始值,之后就没有用 */
- struct timeval {
- long tv_sec; /* 秒 */
- long tv_usec; /* 微妙*/
- };
计时器的实现
- int setitimer(int which, const struct itimerval *value,
- struct itimerval *ovalue)
参数: which:间歇计时器类型,
ITIMER_REAL //数值为0,发送的信号是SIGALRM。
struct itimerval *value:将value指向的结构体设为计时器的当前值,
struct itimerval *ovalue:保存计时器原有值。一般设置为NULL。
返回值: 成功返回0。失败返回-1。
- #include
- #include
- #include
- #include
-
- int x=10,y=10;
- int a=5,b=10;
- void handler(int sig)
- {
- move(a,b);
- addch('B');
- refresh();
- b++;
-
- }
- int main(int argc, const char *argv[])
- {
- char ch;
- initscr();//进入curses模式
- curs_set(0);
- noecho();//禁止字符显示
- keypad(stdscr,1);//允许使用功能键
- start_color();//启动颜色机制
- init_pair(1,COLOR_WHITE, COLOR_RED);
- init_pair(2,COLOR_GREEN,COLOR_WHITE);
-
- signal(SIGALRM, handler);
-
- /*设置定时时间*/
- struct itimerval timer;
- timer.it_value.tv_sec = 3;//首次启动定时时间
- timer.it_value.tv_usec = 0;
- timer.it_interval.tv_sec = 1;//之后每次的定时时间
- timer.it_interval.tv_usec = 0;
- /*启动定时*/
- setitimer(ITIMER_REAL, &timer, NULL);
-
- while(1){
- ch = getch();
- if(ch == 'Q')
- {
- attron(COLOR_PAIR(1));
- move(x,y);
- addch('A');
- refresh();
- y++;
- attroff(COLOR_PAIR(1));
- }
- }
-
- while(1);
- endwin();//退出curses模式
- return 0;
- }
使用信号机制实现每隔1s打印字符串“Flappy bird”,提交代码。
方式1
- #include
- #include
- #include
- #include
-
- void handle(int sig)
- {
-
- printf("Flappy bird\n");
-
- }
-
- int main(int argc,char *argv[])
- {
- struct sigaction act;
- struct itimerval timevalue;
- int ret;
-
-
- act.sa_handler = handle;
- act.sa_flags = 0;
- sigemptyset(&act.sa_mask);
-
- timevalue.it_interval.tv_sec = 1;
- timevalue.it_interval.tv_usec = 0;
- timevalue.it_value.tv_sec = 5;
- timevalue.it_value.tv_usec = 0;
-
- setitimer(ITIMER_REAL, &timevalue,NULL);
- ret = sigaction(SIGALRM,&act,NULL);
-
- if(ret < 0)
- {
- perror("sigaction");
- return 0;
- }
-
-
- while(1)
- {
-
- }
-
- return 0;
- }
方式2
-
- #include
- #include
- #include
- #include
-
- void handle(int sig)
- {
-
- printf("Flappy bird\n");
-
- }
-
- int main(int argc,char *argv[])
- {
-
- struct itimerval timevalue;
-
-
- timevalue.it_interval.tv_sec = 1;
- timevalue.it_interval.tv_usec = 0;
- timevalue.it_value.tv_sec = 5;
- timevalue.it_value.tv_usec = 0;
-
- setitimer(ITIMER_REAL, &timevalue,NULL);
- signal(SIGALRM,handle);
-
-
-
- while(1)
- {
-
- }
-
- return 0;
- }