📄 p10-10.c
字号:
#include <unistd.h>#include <aio.h>#include <stdio.h>#include <signal.h>#include <malloc.h>#include <strings.h>#include "err_exit.h"#define BUF_CNT 2 /* 缓冲区个数 */struct sigaction sig_act;volatile int sigcnt = 0;volatile int total = 0;/* 信号句柄 */void sig_action(int signo, siginfo_t *info, void *context){ printf("Entered sig_action\n"); printf(" signo = %d \n",signo); printf(" si_code = %d \n",info->si_code); printf(" si_value.sival_ptr = %lx hex \n",info->si_value.sival_ptr); /* 从句柄内调aio_error和aio_return。注意si_value是写操作的aiocb。 */ while (aio_error((struct aiocb *)info->si_value.sival_ptr) == EINPROGRESS); /*更新已写的总字节数以设置新的文件位置*/ total += aio_return((struct aiocb *)info->si_value.sival_ptr); sigcnt++; return;}main(int argc, char **argv){ int in_file, out_file, rec_cnt = 0; typedef char *buf_p; buf_p buf[BUF_CNT]; struct aiocb a_write; size_t xfer_size; int buf_index, ret; /* 检查参数个数 */ if (argc < 4) { fprintf(stderr, "Usage: %s input-file output-file buf-size-in-Kb\n", argv[0]); exit(0); } /* 打开输入文件 */ if ((in_file = open(argv[1], O_RDONLY)) == -1) err_exit(argv[1]); printf("Opened Input File\n"); /* 打开输出文件,如果设置O_APPEND标志,所有写都接在文件尾 */ if ((out_file = open(argv[2], O_WRONLY|O_CREAT, 0777)) == -1) err_exit(argv[2]); printf("Opened Output File \n"); /* 计算传送数据大小 (# bufs * 1024) */ xfer_size = atol(argv[3]) * 1024; /* 分配复制文件的缓冲区 */ for (buf_index = 0; buf_index < BUF_CNT; buf_index++) buf[buf_index] = (buf_p)malloc(xfer_size); buf_index = 0; /* 初始SIGUSR1的信号结构 */ sigemptyset(&sig_act.sa_mask); /* 设置SA_SIGINFO标志,信号句柄有三个参数 */ sig_act.sa_flags = SA_SIGINFO; sig_act.sa_sigaction = sig_action; /* 建立SIGUSR1信号句柄 */ printf("Establish Signal Handler for SIGUSR1\n"); if (ret = sigaction (SIGUSR1, &sig_act, 0)) perror("sigaction"); /* 初始aio控制块aiocb */ bzero(&a_write,sizeof(a_write)); a_write.aio_fildes = out_file; a_write.aio_offset = 0; /* 从当前位置开始写 */ a_write.aio_sigevent.sigev_notify = SIGEV_SIGNAL; a_write.aio_sigevent.sigev_signo = SIGUSR1; /* 完成信号 */ /* 填入用户定义的值,它将是生成信号的si_value成份。 * sigev_value的类型是int (sival_int)或void * (sival_ptr)的联合. * 在本例中,我们使用成员sival_ptr,并传递aiocbp的地址给信号句柄, * 以便信号句柄能够直接调aio_error和aio_return。*/ a_write.aio_sigevent.sigev_value.sival_ptr = &a_write; /* 从in_file复制文件到out_file */ while (in_file != -1) { int buf_len; /* 读下一块信息至缓冲 */ buf_len = read( in_file, buf[buf_index], xfer_size); if (rec_cnt) { /* 除第一次之外的所有写都将>1 */ aiocb_t *wait_list = &a_write; /* 等待直到前一个写完成 */ aio_suspend(&wait_list,1,NULL); } /* 检查文件结束条件 */ if (buf_len <= 0) break; /* 为下一次写设置缓冲区 */ a_write.aio_nbytes = buf_len; a_write.aio_buf = buf[buf_index]; /* 若文件是以添加方式打开的,可以忽略offset域 */ a_write.aio_offset = total; ret = aio_write(&a_write); if (ret) err_exit("aio_write"); /* 更新记录计数,并定位至下一缓冲区 */ rec_cnt++; buf_index ^= 1; } printf("total number of bytes written to output file = %d\n",total); /* 关闭文件 */ close(in_file); printf("Closed Input File\n"); close(out_file); printf("Closed Output File\n"); printf("Copied: %d records, %d signals taken\n", rec_cnt, sigcnt);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -