- 浏览: 142357 次
文章分类
最新评论
POSIX 异步 I/O 接口为对不同类型的文件进行异步 I/O 提供了一套一致的方法。这些接口使用 AIO 控制块来描述 I/O 操作。aiocb 结构定义了 AIO 控制块,该结构至少包括下面这些字段:
在 aiocb 结构中,aio_fildes 字段表示被打开用来读或写的文件描述符。读或写操作从 aio_offset 指定的偏移量开始(注意,异步 I/O 操作必须显示地指定偏移量。只要不在同一个进程里把异步 I/O 函数和传统 I/O 函数混在一起用在同一个文件上,异步 I/O 接口是不会影响操作系统维护的文件偏移量的。另外,如果使用异步 I/O 接口向一个以追加模式打开的文件中写入数据,aio_offset 字段会被忽略)。读写数据的操作都是在 aio_buf 指定的缓冲区中进行,aio_nbytes 字段则包含了要读写的字节数。aio_reqprio 为异步 I/O 请求提示顺序(但系统对该顺序的控制力有限,因此不一定遵循)。aio_lio_opcode 字段只能用于基于列表的异步 I/O(见下)。aio_sigevent 使用 sigevent 结构来控制在 I/O 事件完成后,如何通知应用程序。
在 sigevent 结构中,sigev_notify 字段控制通知的类型,其取值可能是以下 3 个中的一个。
(1)SIGEV_NONE:异步 I/O 请求完成后,不通知进程。
(2)SIGEV_SIGNAL:异步 I/O 请求完成后,产生由 sigev_signo 字段指定的信号。如果应用程序已选择捕捉信号,且在建立信号处理程序时指定了 SA_SIGINFO 标志,那么该信号将被入队(如果实现支持排队信号)。信号处理程序会传送给一个 siginfo 结构,该结构的 si_value 字段被设置为 sigev_value(如果使用了 SA_SIGINFO 标志)。
(3)SIGEV_THREAD:当异步 I/O 请求完成时,由 sigev_notify_function 指定的函数会被调用,sigev_value 字段被作为它的唯一参数传入。除非 sigev_notify_attributes 字段被设置为 pthread 属性结构的地址,且该结构指定了另一个线程属性,否则该函数将在分离状态下的一个单独的线程中执行。
进行异步 I/O 之前需要先初始化 AIO 控制块。aio_read 和 aio_write 函数可分别用来进行异步读和异步写操作。
当这些函数返回成功时,异步 I/O 请求便已经被系统放入等待处理的队列中了。这些返回值与实际 I/O 操作的结果没有任何关系。I/O 操作在等待时,必须注意确保 AIO 控制块和数据库缓冲区保持稳定,它们下面对应的内存必须始终是合法的,除非 I/O 操作完成,否则便不能被复用。
要想强制所有等待中的异步操作不等待而写入持久化的存储中,可以调用 aio_fsync 函数。而要获知一个异步读、写或者同步操作的完成状态,可以调用 aio_error 和 aio_return 函数。
aio_fsync 在安排了同步后便返回,在异步同步操作完成前,数据不会被持久化。AIO 控制块中的 aio_fields 字段指定了其异步写操作被同步的文件。如果 op 参数被设置为 O_DSYNC,那么操作执行起来就会像调用了 fdatasync 一样。否则,如果 op 参数被设置为 O_SYNC,则操作执行起来就会像调用了 fsync 一样。
aio_error 的返回值为下面 4 种情况中的一种。
(1)0:表示异步操作成功完成,需要调用 aio_return 函数来获取操作返回值。
(2)-1:表示对 aio_error 的调用失败,这可以通过查看 errno 来获知失败原因。
(3)EINPROGRESS:表示异步读、写或同步操作仍在等待。
(4)其他情况:其他任何的返回值是相关的异步操作失败返回的错误码。
直到异步操作完成之前,都需要小心不要调用 aio_return 函数,否则结果是未定义的。而且还要小心对每个异步操作只调用一次 aio_return,因为一旦调用了该函数,操作系统就可以释放掉包含了 I/O 操作返回值的记录。如果 aio_return 本身失败,就会返回 -1,并设置 errno。否则其他情况下,它将直接返回 read、write 或 fsync 被成功调用时的结果。
执行 I/O 操作时,如果还有其他事务要处理而不想被 I/O 操作阻塞,就可以使用异步 I/O。但如果在完成了所有事务后还有异步操作未完成时,就可以调用 aio_suspend 函数来阻塞进程,直到操作完成。而当还有不想再完成的等待中的异步 I/O 操作时,可以尝试用 aio_cancel 函数来取消它们。
aio_suspend 的 list 参数是一个指向 AIO 控制块数组的指针,nent 参数表明了数组中的条目数,其中的空指针会被跳过,其他条目都必须指向已用于初始化异步 I/O 操作的 AIO控制块。如果该函数被一个信号中断,它会在返回 -1 的同时将 errno 设置为 EINTR,而在阻塞时间超时时,它会将 errno 设置为 EAGAIN(timeout 参数为空指针时表示无时间限制)。
aio_cancel 的 fd 参数指定了那个未完成的异步 I/O 操作的文件描述符。如果 aiocb 参数为 NULL,系统将会尝试取消所有该文件上未完成的异步 I/O 操作。其他情况下,系统将尝试取消由 AIO 控制块描述的单个异步 I/O 操作。之所以说是“尝试”取消,是因为无法保证系统能够取消正在进程中的任何操作。该函数可能会返回以下 4 个值之一:
(1)AIO_ALLDONE:所有操作在尝试取消之前已经完成。
(2)AIO_CANCELED:所以要求的操作已被取消。
(3)AIO_NOTCANCELED:至少有一个要求的操作没有被取消。
(4)-1:函数调用失败,并会设置 errno。
如果异步 I/O 操作被成功取消,则对相应的 AIO 控制块调用 aio_error 函数将会返回 ECANCELED;如果操作不能被取消,则相应的 AIO 控制块不会因为对 aio_cancel 的调用而被修改。
还有一个函数 lio_listio 也被包含在异步 I/O 接口当中,尽管它既能以同步的方式来使用,又能以异步的方式来使用。该函数会提交一系列由一个 AIO 控制块列表描述的 I/O 请求。
其中 mode 参数决定了 I/O 是否真的是异步的:如果该参数被设置为 LIO_WAIT,则该函数将在所有由列表指定的 I/O 操作完成后返回,此时的 sigev 参数将被忽略;如果它被设置为 LIO_NOWAIT,则该函数将在 I/O 请求入队后立即返回,进程会在所有 I/O 操作完成后,按照 sigev 参数指定的事件被异步地通知。如果不想被通知,可以把 sigev 设置为 NULL(注意,每个 AIO 控制块本身也可能启用了在各自操作完成时的异步通知,被 sigev 参数指定的异步通知是在此之外另加的,并且只会在所有的 I/O 操作完成后发送)。
list 参数指向 AIO 控制块列表,该列表指定了要运行的 I/O 操作,其中可以包含 NULL 指针,那些条目会被忽略。nent 参数指定了数组中的元素个数。在每一个 AIO 控制块中,aio_lio_opcode 字段指定了该操作是一个读操作(LIO_READ)、写操作(LIO_WRITE),还是将被忽略的空操作(LIO_NOP)。读操作会按照对应的 AIO 控制块被传给 aio_read 函数处理,写操作则按对应的 AIO 控制块被传给 aio_write 函数处理。
异步 I/O 操作的数量受下表所示的运行时限制。
可以通过调用 sysconf 函数并分别把 name 参数设置为 _SC_IO_LISTIO_MAX、_SC_AIO_MAX 和 _SC_AIO_PRIO_DELTA_MAX 来设置 AIO_LISTIO_MAX、AIO_MAX 和 AIO_PRIO_DELTA_MAX 的值。
下面这个示例演示了如何使用异步 I/O 接口来实现一个 20 世纪 80 年代流行的 USENET 新闻系统中使用的 ROT-13 算法,该算法原本用于将文本中的带有侵犯性的或者含有剧透和笑话笑点部分的文章模糊化,它将文本中的英文字符 a~z 和 A~Z 分别循环向右偏移 13 个字母,其他字符则保持不变(其中为了避免代码臃肿,省略了除 aio_error 和 aio_return 调用之外的返回检测)。
这里使用了 8 个缓冲区,因此可以有最多 8 个异步 I/O 请求处于等待状态。但令人惊讶的是,这可能会降低性能,因为如果读操作是以无序的方式提交给文件系统的,那么操作系统的预读算法便会失效。本示例没有使用异步通知,如果在 I/O 操作进行时还有别的事要做,那么额外的工作可以包含在 for 循环当中。而如果要阻止这些额外的工作延迟翻译文件的任务,就应该考虑使用异步通知。多任务情况下,可能还要考虑各个任务的优先级。
如果将本代码文件作为输入文件运行该程序,可得到下面的结果。
#include <aio.h> struct aiocb{ int aio_fildes; // file descriptor off_t aio_offset; // file offset for I/O volatile void *aio_buf; // buffer for I/O size_t aio_nbytes; // number of bytes to transfer int aio_reqprio; // priority struct sigevent aio_sigevent; // signal information int aio_lio_opcode; // operation for list I/O }; struct sigevent{ int sigev_notify; // notify type int sigev_signo; // signal number union sigval sigev_value; // notify argument void (*sigev_notify_function)(union sigval); // notify function pthread_attr_t *sigev_notify_attributes; // notify attrs };
在 aiocb 结构中,aio_fildes 字段表示被打开用来读或写的文件描述符。读或写操作从 aio_offset 指定的偏移量开始(注意,异步 I/O 操作必须显示地指定偏移量。只要不在同一个进程里把异步 I/O 函数和传统 I/O 函数混在一起用在同一个文件上,异步 I/O 接口是不会影响操作系统维护的文件偏移量的。另外,如果使用异步 I/O 接口向一个以追加模式打开的文件中写入数据,aio_offset 字段会被忽略)。读写数据的操作都是在 aio_buf 指定的缓冲区中进行,aio_nbytes 字段则包含了要读写的字节数。aio_reqprio 为异步 I/O 请求提示顺序(但系统对该顺序的控制力有限,因此不一定遵循)。aio_lio_opcode 字段只能用于基于列表的异步 I/O(见下)。aio_sigevent 使用 sigevent 结构来控制在 I/O 事件完成后,如何通知应用程序。
在 sigevent 结构中,sigev_notify 字段控制通知的类型,其取值可能是以下 3 个中的一个。
(1)SIGEV_NONE:异步 I/O 请求完成后,不通知进程。
(2)SIGEV_SIGNAL:异步 I/O 请求完成后,产生由 sigev_signo 字段指定的信号。如果应用程序已选择捕捉信号,且在建立信号处理程序时指定了 SA_SIGINFO 标志,那么该信号将被入队(如果实现支持排队信号)。信号处理程序会传送给一个 siginfo 结构,该结构的 si_value 字段被设置为 sigev_value(如果使用了 SA_SIGINFO 标志)。
(3)SIGEV_THREAD:当异步 I/O 请求完成时,由 sigev_notify_function 指定的函数会被调用,sigev_value 字段被作为它的唯一参数传入。除非 sigev_notify_attributes 字段被设置为 pthread 属性结构的地址,且该结构指定了另一个线程属性,否则该函数将在分离状态下的一个单独的线程中执行。
进行异步 I/O 之前需要先初始化 AIO 控制块。aio_read 和 aio_write 函数可分别用来进行异步读和异步写操作。
#include <aio.h> int aio_read(struct aiocb *aiocb); int aio_write(struct aiocb *aiocb); /* 两个函数的返回值:若成功,返回 0;否则,返回 -1 */
当这些函数返回成功时,异步 I/O 请求便已经被系统放入等待处理的队列中了。这些返回值与实际 I/O 操作的结果没有任何关系。I/O 操作在等待时,必须注意确保 AIO 控制块和数据库缓冲区保持稳定,它们下面对应的内存必须始终是合法的,除非 I/O 操作完成,否则便不能被复用。
要想强制所有等待中的异步操作不等待而写入持久化的存储中,可以调用 aio_fsync 函数。而要获知一个异步读、写或者同步操作的完成状态,可以调用 aio_error 和 aio_return 函数。
#include <aio.h> int aio_fsync(int op, struct aiocb *aiocb); /* 返回值:若成功,返回 0;否则,返回 -1 */ int aio_error(const struct aiocb *aiocb); ssize_t aio_return(const struct aiocb *aiocb); /* 两个函数的返回值:分别见下 */
aio_fsync 在安排了同步后便返回,在异步同步操作完成前,数据不会被持久化。AIO 控制块中的 aio_fields 字段指定了其异步写操作被同步的文件。如果 op 参数被设置为 O_DSYNC,那么操作执行起来就会像调用了 fdatasync 一样。否则,如果 op 参数被设置为 O_SYNC,则操作执行起来就会像调用了 fsync 一样。
aio_error 的返回值为下面 4 种情况中的一种。
(1)0:表示异步操作成功完成,需要调用 aio_return 函数来获取操作返回值。
(2)-1:表示对 aio_error 的调用失败,这可以通过查看 errno 来获知失败原因。
(3)EINPROGRESS:表示异步读、写或同步操作仍在等待。
(4)其他情况:其他任何的返回值是相关的异步操作失败返回的错误码。
直到异步操作完成之前,都需要小心不要调用 aio_return 函数,否则结果是未定义的。而且还要小心对每个异步操作只调用一次 aio_return,因为一旦调用了该函数,操作系统就可以释放掉包含了 I/O 操作返回值的记录。如果 aio_return 本身失败,就会返回 -1,并设置 errno。否则其他情况下,它将直接返回 read、write 或 fsync 被成功调用时的结果。
执行 I/O 操作时,如果还有其他事务要处理而不想被 I/O 操作阻塞,就可以使用异步 I/O。但如果在完成了所有事务后还有异步操作未完成时,就可以调用 aio_suspend 函数来阻塞进程,直到操作完成。而当还有不想再完成的等待中的异步 I/O 操作时,可以尝试用 aio_cancel 函数来取消它们。
#include <aio.h> int aio_suspend(const struct aiocb *const list[], int nent, const struct timespec *timeout); /* 返回值:若成功,返回 0;否则,返回 -1 */ int aio_cancel(int fd, struct aiocb *aiocb); /* 返回值:见下 */
aio_suspend 的 list 参数是一个指向 AIO 控制块数组的指针,nent 参数表明了数组中的条目数,其中的空指针会被跳过,其他条目都必须指向已用于初始化异步 I/O 操作的 AIO控制块。如果该函数被一个信号中断,它会在返回 -1 的同时将 errno 设置为 EINTR,而在阻塞时间超时时,它会将 errno 设置为 EAGAIN(timeout 参数为空指针时表示无时间限制)。
aio_cancel 的 fd 参数指定了那个未完成的异步 I/O 操作的文件描述符。如果 aiocb 参数为 NULL,系统将会尝试取消所有该文件上未完成的异步 I/O 操作。其他情况下,系统将尝试取消由 AIO 控制块描述的单个异步 I/O 操作。之所以说是“尝试”取消,是因为无法保证系统能够取消正在进程中的任何操作。该函数可能会返回以下 4 个值之一:
(1)AIO_ALLDONE:所有操作在尝试取消之前已经完成。
(2)AIO_CANCELED:所以要求的操作已被取消。
(3)AIO_NOTCANCELED:至少有一个要求的操作没有被取消。
(4)-1:函数调用失败,并会设置 errno。
如果异步 I/O 操作被成功取消,则对相应的 AIO 控制块调用 aio_error 函数将会返回 ECANCELED;如果操作不能被取消,则相应的 AIO 控制块不会因为对 aio_cancel 的调用而被修改。
还有一个函数 lio_listio 也被包含在异步 I/O 接口当中,尽管它既能以同步的方式来使用,又能以异步的方式来使用。该函数会提交一系列由一个 AIO 控制块列表描述的 I/O 请求。
#include <aio.h> int lio_listio(int mode, struct aiocb *restrict const list[restrict], int nent, struct sigevent *restrict sigev); /* 返回值:若成功,返回 0;否则,返回 -1 */
其中 mode 参数决定了 I/O 是否真的是异步的:如果该参数被设置为 LIO_WAIT,则该函数将在所有由列表指定的 I/O 操作完成后返回,此时的 sigev 参数将被忽略;如果它被设置为 LIO_NOWAIT,则该函数将在 I/O 请求入队后立即返回,进程会在所有 I/O 操作完成后,按照 sigev 参数指定的事件被异步地通知。如果不想被通知,可以把 sigev 设置为 NULL(注意,每个 AIO 控制块本身也可能启用了在各自操作完成时的异步通知,被 sigev 参数指定的异步通知是在此之外另加的,并且只会在所有的 I/O 操作完成后发送)。
list 参数指向 AIO 控制块列表,该列表指定了要运行的 I/O 操作,其中可以包含 NULL 指针,那些条目会被忽略。nent 参数指定了数组中的元素个数。在每一个 AIO 控制块中,aio_lio_opcode 字段指定了该操作是一个读操作(LIO_READ)、写操作(LIO_WRITE),还是将被忽略的空操作(LIO_NOP)。读操作会按照对应的 AIO 控制块被传给 aio_read 函数处理,写操作则按对应的 AIO 控制块被传给 aio_write 函数处理。
异步 I/O 操作的数量受下表所示的运行时限制。
可以通过调用 sysconf 函数并分别把 name 参数设置为 _SC_IO_LISTIO_MAX、_SC_AIO_MAX 和 _SC_AIO_PRIO_DELTA_MAX 来设置 AIO_LISTIO_MAX、AIO_MAX 和 AIO_PRIO_DELTA_MAX 的值。
下面这个示例演示了如何使用异步 I/O 接口来实现一个 20 世纪 80 年代流行的 USENET 新闻系统中使用的 ROT-13 算法,该算法原本用于将文本中的带有侵犯性的或者含有剧透和笑话笑点部分的文章模糊化,它将文本中的英文字符 a~z 和 A~Z 分别循环向右偏移 13 个字母,其他字符则保持不变(其中为了避免代码臃肿,省略了除 aio_error 和 aio_return 调用之外的返回检测)。
#include <stdio.h> #include <stdlib.h> #include <aio.h> #include <ctype.h> #include <fcntl.h> #include <sys/stat.h> #include <errno.h> #define BSZ 40 //4096 #define NBUF 8 #define FILE_MODE (S_IRUSR |S_IWUSR |S_IRGRP |S_IROTH) enum rwop{ UNUSED = 0, READ_PENDING = 1, WRITE_PENDING = 2 }; struct buf{ enum rwop op; int last; struct aiocb aiocb; unsigned char data[BSZ]; }; struct buf bufs[NBUF]; unsigned char translate(unsigned char c){ if(isalpha(c)){ if(c >= 'n') c -= 13; else if(c >= 'a') c += 13; else if(c >= 'N') c -= 13; else c += 13; } return c; } int main(int argc, char *argv[]){ if(argc != 3){ printf("usage: %s <infile> <outfile>\n", argv[0]); exit(1); } int ifd = open(argv[1], O_RDONLY); int ofd = open(argv[2], O_RDWR |O_CREAT |O_TRUNC, FILE_MODE); struct stat sbuf; fstat(ifd, &sbuf); const struct aiocb *aiolist[NBUF]; int i, j; for(i=0; i<NBUF; i++){ // initialize the buffers bufs[i].op = UNUSED; bufs[i].aiocb.aio_buf = bufs[i].data; bufs[i].aiocb.aio_sigevent.sigev_notify = SIGEV_NONE; aiolist[i] = NULL; } int numop = 0; off_t off = 0; for(;;){ for(i=0; i<NBUF; i++){ int n, err; switch(bufs[i].op){ case UNUSED: if(off < sbuf.st_size){ bufs[i].op = READ_PENDING; bufs[i].aiocb.aio_fildes = ifd; bufs[i].aiocb.aio_offset = off; off += BSZ; if(off >= sbuf.st_size) bufs[i].last = 1; bufs[i].aiocb.aio_nbytes = BSZ; aio_read(&bufs[i].aiocb); aiolist[i] = &bufs[i].aiocb; numop++; } break; case READ_PENDING: if((err = aio_error(&bufs[i].aiocb)) == EINPROGRESS) continue; if(err != 0){ if(err == -1) printf("aio_error failed\n"); else printf("read failed, errno = %d\n", err); continue; } if((n = aio_return(&bufs[i].aiocb)) < 0){ printf("aio_return failed\n"); continue; } if(n != BSZ && !bufs[i].last) printf("short read (%d/%d)\n", n, BSZ); for(j=0; j<n; j++) // translate the buffer bufs[i].data[j] = translate(bufs[i].data[j]); bufs[i].op = WRITE_PENDING; bufs[i].aiocb.aio_fildes = ofd; bufs[i].aiocb.aio_nbytes = n; aio_write(&bufs[i].aiocb); break; // retain our spot in aiolist case WRITE_PENDING: if((err = aio_error(&bufs[i].aiocb)) == EINPROGRESS) continue; if(err != 0){ if(err == -1) printf("aio_error failed\n"); else printf("read failed, errno = %d\n", err); continue; } if((n = aio_return(&bufs[i].aiocb)) < 0){ printf("aio_return failed\n"); continue; } if(n != bufs[i].aiocb.aio_nbytes) printf("short write (%d/%d)\n", n, BSZ); aiolist[i] = NULL; bufs[i].op = UNUSED; numop--; break; } } if(numop == 0) if(off >= sbuf.st_size) break; else aio_suspend(aiolist, NBUF, NULL); } bufs[0].aiocb.aio_fildes = ofd; aio_fsync(O_SYNC, &bufs[0].aiocb); exit(0); }
这里使用了 8 个缓冲区,因此可以有最多 8 个异步 I/O 请求处于等待状态。但令人惊讶的是,这可能会降低性能,因为如果读操作是以无序的方式提交给文件系统的,那么操作系统的预读算法便会失效。本示例没有使用异步通知,如果在 I/O 操作进行时还有别的事要做,那么额外的工作可以包含在 for 循环当中。而如果要阻止这些额外的工作延迟翻译文件的任务,就应该考虑使用异步通知。多任务情况下,可能还要考虑各个任务的优先级。
如果将本代码文件作为输入文件运行该程序,可得到下面的结果。
$ gcc -lrt aio_rot13.c -o aio_rot13.out # 编译文件 $ ./aio_rot13.out aio_rot13.c aio.test # 执行程序 $ head -n 5 aio.test # 查看翻译后的文件的前五行 #vapyhqr <fgqvb.u> #vapyhqr <fgqyvo.u> #vapyhqr <nvb.u> #vapyhqr <pglcr.u> #vapyhqr <spagy.u> $
发表评论
-
打开伪终端设备
2018-07-09 20:50 1252在伪终端概述一节中已对 PTY进行了初步的介绍。尽管 ... -
伪终端概述
2018-06-02 11:05 1548伪终端就是指,一个应用程序看上去像一个终端,但事实上它 ... -
终端窗口大小和 termcap
2018-05-29 22:39 799多数 UNIX 系统都提供了一种跟踪当前终端窗口大小的 ... -
终端规范模式和非规范模式
2018-05-29 00:25 949终端规范模式很简单:发一个读请求,当一行已经输入后,终 ... -
终端标识
2018-05-23 11:18 568尽管控制终端的名字在多数 UNIX 系统上都是 /de ... -
波特率和行控制函数
2018-05-22 07:53 943虽然大多数终端设 ... -
终端属性和选项标志
2018-05-20 07:40 709tcgetattr 和 tcsetattr ... -
终端特殊输入字符
2018-05-17 06:33 814终端支持下表所示的特殊输入字符。 为了更改 ... -
终端 I/O 综述
2018-05-10 07:56 437终端设备可认为是由内核中的终端驱动程序控制的。每个终端 ... -
POSIX 信号量
2018-05-09 00:03 579在XSI IPC通信之信 ... -
XSI IPC 通信之共享存储
2018-04-25 07:18 946在XSI IPC通信之消息队列和XSI IPC通信之信 ... -
XSI IPC通信之信号量
2018-04-17 23:38 616在XSI IPC通信之消 ... -
XSI IPC通信之消息队列
2018-04-15 10:54 497消息队列是消息的链接表,存储在内核中,由消息队列标识符 ... -
XSI IPC 相似特征介绍
2018-02-08 23:48 485有 3 种称作 XSI IPC ... -
IPC 通信之 FIFO
2018-02-06 22:55 421FIFO 也被称为命名管道,未命名的管道只能在两个相关 ... -
IPC 通信之管道
2018-01-30 22:22 389管道是 UNIX 系统 IPC 的最古老但也是最常用的 ... -
readv/writev 函数及存储映射 I/O
2018-01-19 00:57 889readv 和 writev 函数可用于在一次函数调用 ... -
fcntl 记录锁
2018-01-06 23:48 615记录锁的功能是:当有进程正在读或修改文件的某个部分时, ... -
守护进程惯例
2018-01-06 23:52 439UNIX 系统中,守护进程遵循下列通用惯例。 ... -
守护进程编写规则与出错记录
2017-12-26 01:53 454在编写守护进程程 ...
相关推荐
GLIBC(GNU C Library)是Linux系统中广泛使用的C语言库,它提供了对POSIX标准异步I/O函数的支持,实现了用户级线程的方式来模拟异步I/O。 异步I/O的基本思想是,应用程序发起I/O请求后,不再等待操作完成,而是...
除了基本的I/O操作外,还有其他高级I/O机制,例如异步I/O、内存映射文件和缓冲I/O等。异步I/O允许程序在等待I/O操作完成时继续执行其他任务,提高了效率。内存映射文件将文件内容映射到进程的虚拟地址空间,使得访问...
需要检查 OS 补丁,创建用户和组,更改 OS 参数,配置 rhosts 文件,运行 rootpre.sh 并重启 HACMP,配置 Asynchronous I/O 和 POSIX 异步 I/O,配置 HACMP 组服务,添加 Oracle 用户到组,并重启 HACMP。
为了解决这个问题,POSIX异步I/O(AIO)API应运而生,它允许应用程序发起I/O操作而不必等待其完成,从而提高了程序的并发性和效率。 AIO简介: Linux异步I/O是在2.6内核版本中引入的一项功能,但在2.4内核中也有...
同步I/O在进行数据传输时会阻塞进程,直到I/O操作完成,而异步I/O则在发起I/O请求后,操作系统会负责后续的数据传输过程,不会阻塞进程,程序可以继续执行其他任务,当I/O操作完成时,操作系统通过回调函数或Future...
它使用C语言编写,并依赖于libaio库来实现异步I/O操作。此外,fio还支持在不同的操作系统上运行,如Linux、FreeBSD、Solaris等。 #### 邮件列表 fio有一个活跃的邮件列表,用户可以在其中讨论问题、分享经验并提出...
史蒂文斯在《UNIX网络编程》中介绍了五种基本的I/O模型:阻塞I/O、非阻塞I/O、I/O多路复用(如select和poll)、信号驱动的I/O(SIGIO)以及异步I/O(POSIX的aio_functions)。阻塞I/O是最基础的模型,当调用I/O操作...
重叠IO模型属于异步I/O的一种,但与标准的异步I/O(如POSIX的aio_*函数)不同,它在Windows操作系统中被广泛使用,被称为完成端口(I/O Completion Ports,IOCP)。 重叠IO模型的工作流程如下: 1. **初始化**:...
- POSIX异步I/O支持:允许程序发起异步读写操作,不会阻塞程序继续执行。 - mmap()文件I/O:内存映射文件I/O可以提高大文件处理的效率。 - 普通文件I/O:支持常规的文件读写操作。 - 单一数据流测试:可以测量单个...
### 异步I/O编程概览 #### 一、引言 本次讲座由Henrik Thostrup Jensen在2006年4月20日进行,主题为《异步I/O编程》。讲座旨在探讨异步I/O的概念、优势、挑战以及如何在实际编程中应用这些技术。 #### 二、什么是...
AIO是POSIX标准定义的一种异步I/O接口,但Linux的实现并不完善。Linux提供了一个替代方案,即上述的epoll配合非阻塞I/O来模拟异步I/O行为。 8. **管道和FIFO** 管道和FIFO(有名管道)是进程间通信(IPC)的一种...
在POSIX兼容的系统上,例如Linux系统,I/O操作可以有多种方式,比如DIO(Direct I/O),AIO(Asynchronous I/O 异步I/O),Memory-Mapped I/O(内存映设I/O)等,不同的I/O方式有不同的实现 方式和性能,在不同的应用中可以...
异步 I/O 是通过 POSIX AIO API 实现的,这一 API 在 Linux 2.6 内核中成为标准特性,但在 2.4 内核中也有相应的补丁支持。 AIO 的核心理念是发起 I/O 操作后,进程可以立即返回并执行其他任务,而不是等待 I/O ...
- **AIO_read/AIO_write:** 使用POSIX异步I/O API进行读写。 - **Mmap:** 使用内存映射文件进行读写。 **特性:** - 使用ANSI C编写。 - 支持POSIX异步I/O。 - 支持使用`mmap()`进行文件I/O。 - 支持普通文件I/O。 ...
libeio则是一个用于C语言的全功能异步I/O库,提供异步版本的POSIX API,包括读取、写入、打开、关闭、统计等文件操作。 在Node.js中,异步接口的实现主要包括使用uv(libuv)封装的libev事件循环,以及在Windows...
在I/O系统方面,VxWorks兼容ANSI C和UNIX的I/O标准,如基本I/O和Buffer I/O,同时也支持POSIX异步I/O。系统内包含多种设备驱动程序,如网络、管道、RAM盘、SCSI、键盘、显示、硬盘、并口等,满足不同硬件设备的需求...
- `aio_physmem_pct` 设定了为POSIX异步I/O操作锁定的物理内存最大百分比,默认为10%。 - `aio_prio_delta_max` 是AIO请求优先级的最大降低值,影响I/O操作的调度,默认值为20。 3. **Dump Parameters(转储参数...
例如,阻塞I/O适合简单应用,非阻塞I/O适合多任务环境,I/O复用适合多socket管理,信号驱动I/O在实时系统中有用,而异步I/O则提供了最高级别的并行性和性能。开发者需要根据应用需求选择合适的模型。在实际应用中,...
通过root用户使用`smit`命令,配置Posix异步I/O为可用状态。 6. **Informatica 8.6安装**: - 使用提供的`install.bin`脚本以控制台模式进行安装,`–i console`参数指定安装模式。 - 安装过程中,选择合适的语言...