지금 프로젝트에서 작성한 프로그램의 개선점을 찾다보니, 비동기 작업 처리를 위해 aio를 이용하면 좋을듯 하다. 아래 사이트 내용을 참조하여 완전한 예제로 구성해보았다.
http://www.ibm.com/developerworks/linux/library/l-async/
컴파일은 gcc -lrt -o aioTest aioTest.c 으로 수행.
file.txt 내용은 다음과 같다.
123456789abcdefghijklmnopqrstuvwxyz
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 | //aioTest.c // gcc -lrt -o aioTest aioTest.c // librt" stands for "real time library". ////////////////////////////////////////////////////////////////// // busy-wait until the status changes void { printf("\n\n==================================================\n"); int fd, ret; //int BUFSIZE = 10240; int BUFSIZE = 5; ; fd = open( "file.txt", O_RDONLY ); if (fd < 0) perror("open"); /* Zero out the aiocb structure (recommended) */ bzero( (char *)&my_aiocb, sizeof( ) ); /* Allocate a data buffer for the aiocb request */ my_aiocb.aio_buf = malloc(BUFSIZE+1); if (!my_aiocb.aio_buf) perror("malloc"); /* Initialize the necessary fields in the aiocb */ my_aiocb.aio_fildes = fd; my_aiocb.aio_nbytes = BUFSIZE; my_aiocb.aio_offset = 0; //the first offset in the file //below block aio ///////////////////////////////// int MAX_LIST = 1; [MAX_LIST]; /* Clear the list. */ bzero( (char *)cblist, sizeof(cblist) ); /* Load one or more references into the list */ cblist[0] = &my_aiocb; //below block aio ///////////////////////////////// ret = aio_read( &my_aiocb ); //below block aio ///////////////////////////////// ret = aio_suspend( cblist, MAX_LIST, NULL ); //below block aio ///////////////////////////////// if (ret < 0) perror("aio_read"); while == EINPROGRESS ) { printf("busy waiting...\n"); } if ) > 0) { /* got ret bytes on the read */ printf("ret [%d]\n", ret); //print buffer printf("buff[%s]\n",my_aiocb.aio_buf); } else { /* read failed, consult errno */ printf("read failed\n"); } } ////////////////////////////////////////////////////////////////// // lio_listio , Initiate a list of I/O operations // with busy waiting void { printf("\n\n==================================================\n"); int fd, ret; //int BUFSIZE = 10240; int BUFSIZE = 5; int MAX_LIST = 2; , aiocb2; [MAX_LIST]; fd = open( "file.txt", O_RDONLY ); if (fd < 0) perror("open"); /* Zero out the aiocb structure (recommended) */ bzero( (char *)&aiocb1, sizeof( ) ); bzero( (char *)&aiocb2, sizeof( ) ); //aiocb1 aiocb1.aio_fildes = fd; aiocb1.aio_buf = malloc(BUFSIZE+1); aiocb1.aio_nbytes = BUFSIZE; aiocb1.aio_offset = 0; //the first offset in the file aiocb1.aio_lio_opcode = LIO_READ; //aiocb2 aiocb2.aio_fildes = fd; aiocb2.aio_buf = malloc(BUFSIZE+1); aiocb2.aio_nbytes = BUFSIZE; aiocb2.aio_offset = BUFSIZE; //!!! aiocb2.aio_lio_opcode = LIO_READ; bzero( (char *)list, sizeof(list) ); list[0] = &aiocb1; list[1] = &aiocb2; //WAIT //ret = lio_listio( LIO_WAIT, list, MAX_LIST, NULL ); // NO_WAIT ret = lio_listio( LIO_NOWAIT, list, MAX_LIST, NULL ); while ( aio_error( &aiocb1 ) == EINPROGRESS || aio_error( &aiocb2 ) == EINPROGRESS ) { printf("busy waiting...\n"); } // NO_WAIT //aiocb1 if ) > 0) { printf("\n******\n"); printf("aiocb1 ret [%d]\n", ret); printf("aiocb1 buff[%s]\n",aiocb1.aio_buf); } else { /* read failed, consult errno */ printf("aiocb1 read failed\n"); } //aiocb2 if ) > 0) { printf("\n******\n"); printf("aiocb2 ret [%d]\n", ret); printf("aiocb2 buff[%s]\n",aiocb2.aio_buf); } else { /* read failed, consult errno */ printf("aiocb2 read failed\n"); } } ////////////////////////////////////////////////////////////////// //aio with callback //also available : Asynchronous notification with signals ; void { printf("aio_completion_handler\n"); ; req = ( )sigval.sival_ptr; /* Did the request complete? */ if == 0) { /* Request completed successfully, get the return status */ int ret = aio_return( req ); printf("ret [%d]\n", ret); printf("buff[%s]\n",req->aio_buf); } return; } void { printf("\n\n==================================================\n"); int fd, ret; //int BUFSIZE = 10240; int BUFSIZE = 20; fd = open( "file.txt", O_RDONLY ); if (fd < 0) perror("open"); /* Set up the AIO request */ bzero( (char *)&my_aiocb, sizeof( ) ); my_aiocb.aio_fildes = fd; my_aiocb.aio_buf = malloc(BUFSIZE+1); my_aiocb.aio_nbytes = BUFSIZE; my_aiocb.aio_offset = 0; /* Link the AIO request with a thread callback */ my_aiocb.aio_sigevent.sigev_notify = SIGEV_THREAD; my_aiocb.aio_sigevent.sigev_notify_function = aio_completion_handler; my_aiocb.aio_sigevent.sigev_notify_attributes = NULL; my_aiocb.aio_sigevent.sigev_value.sival_ptr = &my_aiocb; ret = aio_read( &my_aiocb ); } ////////////////////////////////////////////////////////////////// int { testBusyWait(); testListio(); testCallback(); while(1) { sleep(1); } } |
수행 결과는 다음과 같다.
==============================================================
ret [5]
buff[12345]
==============================================================
aiocb1 busy waiting...
aiocb1 busy waiting...
.....
aiocb1 busy waiting...
******
aiocb1 ret [5]
aiocb1 buff[12345]
******
aiocb2 ret [5]
aiocb2 buff[6789a]
==============================================================
aio_completion_handler
ret [20]
buff[123456789abcdefghijk]
글 잘 보았습니다.
답글삭제aio library와 libaio library의 차이점이 있네요. 아래글 참고하세요~^^
http://stackoverflow.com/questions/8768083/difference-between-posix-aio-and-libaio-on-linux