lv6 嵌入式开发-Flappy bird项目(信号机制、定时器功能实现)

目录

1 信号(signal)

2 设置信号响应方式 – signal

3 设置定时器

4 示例


问题:

getch()阻塞获取键盘按键输入, 怎么操作才能不影响小鸟下落和管道移动?

getch如果阻塞,下面的程序都是无法执行。通过信号机制方式实现。

1 信号(signal)

在Linux中,软中断信号(signal,简称为信号)是在软件层次上对中断的一种模拟,用来通知进程发生了异步事件。内核可以因为内部事件而给进程发送信号,通知进程发生了某个事件。

信号响应的方式:

1.忽略信号,即对信号不做任何处理;

2.捕捉信号,即信号发生时执行用户自定义的信号处理函数。

3.执行缺省操作,Linux对每种信号都规定了默认操作。

信号的检测与处理流程图

lv6 嵌入式开发-Flappy bird项目(信号机制、定时器功能实现)_第1张图片

2 设置信号响应方式 – signal

#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;
}

3 设置定时器

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。

4 示例

#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;
}

5 练习

使用信号机制实现每隔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;
}

你可能感兴趣的:(嵌入式开发,linux)