The sample of O_ASYNC and aio_read

原创 2007年09月27日 10:20:00
O_ASYNC 和 aio_read 示例代码, 主要用来示范Linux中的信号量.

代码为一个游戏,用*去捕捉小球,
Q --退出
S,s,F,f --加快或减缓小球x或y方向移动速度
z,x--改变小球x或y轴移动方向
i,j,k,l 移动*号.

bounce.h:
/* bounce.h
 * somet settings for the game
 
*/

#ifndef bounce_h
    
#define bounce_h

    #include 
<aio.h>
    #include 
<curses.h>
    #include 
<fcntl.h>
    #include 
<string.h>
    #include 
<unistd.h>

    
#define BLANK ' '
    
#define DFL_SYMBOL 'o'
    
#define PL_SYMBOL '*'
    
#define TOP_ROW 5
    
#define BOT_ROW 20
    
#define LEFT_EDGE 10
    
#define RIGHT_EDGE 70
    
#define X_INIT 10                // starting col
    
#define Y_INIT 10                // starting row
    
#define TICKS_PER_SEC 50            // affects speed
    
#define X_TTM 8
    
#define Y_TTM 8

    
int done = 0;
    
int score = 0;

    
// the ping pong ball
    struct ppball{
        
int y_pos,x_pos,
            y_ttm,x_ttm,
            y_ttg,x_ttg,
            y_dir,x_dir;
        
char symbol;
    }
;

    
// the player
    struct player {
        
int y_pos,x_pos;
        
char symbol;
    }
;

    
struct aiocb kbcbuf;
    
struct ppball the_ball;
    
struct player the_player;

    
int set_ticker(int);
    
void draw_wall();
    
void draw_score();
    
void draw_player();
    
void move_player(char);
#endif
bounce2d.c:
/* bounce2d 1.0
 * bounce a character (defaults is 'o') around the screen
 * defined by some paraments
 *
 * user input: 
 *     s slow down x component, S: slow y component
 *     f speed up x component, F: speed y component
 *     Q quit
 * 
 * purpose animation with use control, using aio_read() or O_ASYNC
 * timer tick sends SIGALRM, handler does animation
 * keybords sends SIGIO
 * main only class pause()
 * build: cc bounce2d.c set_ticker.c -lcurses -l rt-o bounce2d
 
*/

#include 
"bounce.h"


// the main loop

void set_up();
void wrap_up();

int main() {
    set_up();

    
while(!done)                     // the main loop
        pause();
    
    wrap_up();

    
return 0;
}


/*
 * init structure and other stuff
 
*/

void set_up() {
    
void ball_move(int);
    
void enable_kdb_signals();
    
void setup_aio_buffer();
    
void on_input(int);

    
// setup the ball's state
    the_ball.y_pos = Y_INIT;        
    the_ball.x_pos 
= X_INIT;
    the_ball.y_ttg 
= the_ball.y_ttm = Y_TTM;
    the_ball.x_ttg 
= the_ball.x_ttm = X_TTM;
    the_ball.y_dir 
= 1;
    the_ball.x_dir 
= 1;
    the_ball.symbol 
= DFL_SYMBOL;

    done 
= 0;

    initscr();                    
// setup the screen
    noecho();
    crmode();
    clear();
    
    
// setup the player's state and draw the player
    the_player.x_pos = LEFT_EDGE;
    the_player.y_pos 
= TOP_ROW;
    the_player.symbol 
= PL_SYMBOL;
    draw_player();

    
// draw the wall
    draw_wall();

    
// setup and draw the score
    score = 0;
    draw_score();

    signal(SIGINT,SIG_IGN);
    mvaddch(the_ball.y_pos,the_ball.x_pos,the_ball.symbol);
    refresh();

    signal(SIGIO,on_input);                
// install a handler
    
    
// use O_ASYNC
//    enable_kdb_signals();                // turn on kbd signals
    
    
// use aio_read
    setup_aio_buffer();                // initialize aio ctrl buff
    aio_read(&kbcbuf);                // place a read quest

    signal(SIGALRM,ball_move);            
// install alarm handler
    set_ticker(1000/TICKS_PER_SEC);            // send millisecs per tick
}


void wrap_up() {
    set_ticker(
0);
    endwin();                    
// put back normal
}


void ball_move(int signum) {
    
int y_cur,x_cur,moved;
    
    
int bounce_or_lose(struct ppball *);

    signal(SIGALRM,ball_move);            
// don't get caught now
    y_cur = the_ball.y_pos;                // old spot
    x_cur = the_ball.x_pos;
    moved 
= 0;

    
if(the_ball.y_ttm > 0 && --the_ball.y_ttg == 0{
        the_ball.y_pos 
+= the_ball.y_dir;    // move
        the_ball.y_ttg = the_ball.y_ttm;    // reset
        moved = 1;
    }


    
if(the_ball.x_ttm > 0 && --the_ball.x_ttg == 0{
        the_ball.x_pos 
+= the_ball.x_dir;    // move
        the_ball.x_ttg = the_ball.x_ttm;    // reset
        moved = 1;
    }


    
if(moved) {
        mvaddch(y_cur,x_cur,BLANK);
        
// mvaddch(y_cur,x_cur,BLANK);
        mvaddch(the_ball.y_pos,the_ball.x_pos,the_ball.symbol);
        
if(bounce_or_lose(&the_ball)) {
            
++score;
            draw_score();
            draw_wall();
        }

        move(LINES 
- 1,COLS - 1);
        refresh();
    }

    signal(SIGALRM,ball_move);            
//  for unreliable systems
}


int bounce_or_lose(struct ppball *bp) {
    
int return_val = 0;

    
if(bp -> y_pos <= TOP_ROW) {
        bp 
-> y_dir = 1;
    }
 else if(bp -> y_pos >= BOT_ROW) {
        bp 
-> y_dir = -1;
    }


    
if(bp -> x_pos <= LEFT_EDGE) {
        bp 
-> x_dir = 1;
    }
 else if(bp -> x_pos >= RIGHT_EDGE) {
        bp 
-> x_dir = -1;
    }


    
if(bp -> x_pos == the_player.x_pos 
        
&& bp -> y_pos == the_player.y_pos)
        return_val 
= 1;

    
return return_val;
}


/* 
 * intstall a handler, tell kernel who to notify on input, enable signals
 
*/

void enable_kdb_signals() {
    
int fd_flags;

    fcntl(
0,F_SETOWN,getpid());
    fd_flags 
= fcntl(0,F_GETFL);
    fcntl(
0,F_SETFL,(fd_flags | O_ASYNC));
}


/*
 * handler called to when aio_read() has stuff to read
 * First check for any errors codes, and if ok, then get the return code
 
*/

void on_input(int signum) {
    
int c;

    
while((c = getchar()) != 'Q'{
        
if(c == 'f'--the_ball.x_ttm;
        
else if(c == 's'++the_ball.x_ttm;
        
else if(c == 'F'--the_ball.y_ttm;
        
else if(c == 'S'++the_ball.y_ttm;
        
else if(c == 'z'
            the_ball.x_dir 
= -the_ball.x_dir;
        
else if(c == 'x')
            the_ball.y_dir 
= -the_ball.y_dir;
        
else if(c == 'i' || c == 'j' || c == 'k' || c == 'l')
            move_player(c);
    }


    done 
= 1;
}


/*
 * set memebers of struct
 * First specify args like those for read(fd,buf,num) and offset
 * Then specify what to do(send signal) and what signal(SIGIO)
 
*/

void setup_aio_buffer() {
    
static char input[1];                // 1 char of input

    
// describe what to read
    kbcbuf.aio_fildes = 0;                // standard input
    kbcbuf.aio_buf = input;                // buffer
    kbcbuf.aio_nbytes = 1;                // number to read
    kbcbuf.aio_offset = 0;                // offset in file

    
// describe what to do when read is ready
    kbcbuf.aio_sigevent.sigev_notify = SIGEV_SIGNAL;
    kbcbuf.aio_sigevent.sigev_signo 
= SIGIO;    // send SIGIO
}


/*
 * draw the wall when setup.
 
*/

void draw_wall() {
    
int i,j;
    
    
// draw four corner
    mvaddch(TOP_ROW - 1,LEFT_EDGE - 1,'+');
    mvaddch(BOT_ROW 
+ 1,LEFT_EDGE - 1,'+');
    mvaddch(TOP_ROW 
- 1,RIGHT_EDGE + 1,'+');
    mvaddch(BOT_ROW 
+ 1,RIGHT_EDGE + 1,'+');

    
// draw top row
    for(i = LEFT_EDGE,j = TOP_ROW - 1; i <= RIGHT_EDGE; ++i) {
        mvaddch(j,i,
'-');
    }


    
// draw left column
    for(i = LEFT_EDGE - 1,j = TOP_ROW; j <= BOT_ROW; ++j) {
        mvaddch(j,i,
'|');
    }


    
// draw botton row
    for(i = LEFT_EDGE,j = BOT_ROW + 1; i <= RIGHT_EDGE; ++i) {
        mvaddch(j,i,
'-');
    }


    
// draw right column
    for(i = RIGHT_EDGE + 1,j = TOP_ROW; j <= BOT_ROW; ++j) {
        mvaddch(j,i,
'|');
    }

}


/*
 * draw score on the left top corner
 
*/

void draw_score() {
    
char score_string[100];
    sprintf(score_string,
"score:%d",score);
    move(
1,1);
    addstr(score_string);
}


/*
 * draw the player
 
*/

void draw_player() {
    mvaddch(the_player.y_pos,the_player.x_pos,the_player.symbol);    
}


/*
 * move the player
 
*/

void move_player(char input) {
    mvaddch(the_player.y_pos,the_player.x_pos,BLANK);    
    
switch(input) {
        
case 'i':
            
if(the_player.y_pos > TOP_ROW)
                
--the_player.y_pos;
            
break;
        
case 'k':
            
if(the_player.y_pos < BOT_ROW)
                
++the_player.y_pos;
            
break;
        
case 'j':
            
if(the_player.x_pos > LEFT_EDGE)
                
--the_player.x_pos;
            
break;
        
case 'l':
            
if(the_player.x_pos < RIGHT_EDGE)
                
++the_player.x_pos;
            
break;
    }

    draw_player();
}

set_ticker.c:
#include    <stdio.h>
#include        
<sys/time.h>
#include        
<signal.h>

/*
 *      set_ticker.c
 *          set_ticker( number_of_milliseconds )
 *                   arranges for the interval timer to issue
 *                   SIGALRM's at regular intervals
 *          returns -1 on error, 0 for ok
 *
 *      arg in milliseconds, converted into micro seoncds
 
*/



int set_ticker( int n_msecs )
{
        
struct itimerval new_timeset;
        
long    n_sec, n_usecs;

        n_sec 
= n_msecs / 1000 ;
        n_usecs 
= ( n_msecs % 1000 ) * 1000L ;

        new_timeset.it_interval.tv_sec  
= n_sec;        /* set reload  */
        new_timeset.it_interval.tv_usec 
= n_usecs;      /* new ticker value */
        new_timeset.it_value.tv_sec     
= n_sec  ;      /* store this   */
        new_timeset.it_value.tv_usec    
= n_usecs ;     /* and this     */

    
return setitimer(ITIMER_REAL, &new_timeset, NULL);
}



makefile:
bounce2d: bounce2d.c bounce.h set_ticker.c
    gcc 
$^ -l curses -l rt -o $@ -Wall
版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

Linux下异步I/0:O_ASYNC标志,aio_read

http://blog.csdn.net/wenhuiqiao/article/details/7066267 方法一:使用fcntl来置O_ASYNC位。            ...

Linux下异步I/0:O_ASYNC标志,aio_read

方法一:使用fcntl来置O_ASYNC位。              这个方法的效果是,当输入缓存中的输入数据就绪时(输入数据可读),内核向用F_SETO...

Read and Write sample on Cassandra by using Aquiles...

1. You need set your config file. Web.config or App.config

<Ejb3InAction> Sample02 for Glassfish - Simple example of Stateless, Stateful, MDB and JPA Enity

0. Prerequisite 1) JDBC resources We use default JDBC resources, which is based on database sun-ap...

<Ejb3InAction> Sample02 for Weblogic - Simple example of Stateless, Stateful, MDB and JPA Enity

0. Prerequisite Actually this sample is postponed, please reference to prerequisites of sample03 a...

Investigation report of MSSQL data read and write performance

MSSQL 2008 CPU Xeon E5 2G (12 CORE ) X 2 RAM 128G case 1: while @i<1,000,000 begin Insert into T1( ...

Read and write excel file with format by pandas and xlwt libraries of python

Read and write excel file with format by pandas and xlwt libraries of python
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)