首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    使用异步I/O大大提高应用程序的性能

    aio_return 异步 I/O 和标准块 I/O 之间的另外一个区别是我们不能立即访问这个函数的返回状态,因为我们并没有阻塞在 read 调用上。在标准的 read 调用中,返回状态是在该函数返回时提供的。但是在异步 I/O 中,我们要使用 aio_return 函数。这个函数的原型如下: ssize_t aio_return( struct aiocb *aiocbp ); 只有在 aio_error 调用确定请求已经完成(可能成功,也可能发生了错误)之后,才会调用这个函数。aio_return 的返回值就等价于同步情况中 read 或 write 系统调用的返回值(所传输的字节数,如果发生错误,返回值就为 -1)。 aio_write aio_write 函数用来请求一个异步写操作。其函数原型如下: int aio_write( struct aiocb *aiocbp ); aio_write 函数会立即返回,说明请求已经进行排队(成功时返回值为 0,失败时返回值为 -1,并相应地设置 errno)。 这与 read 系统调用类似,但是有一点不一样的行为需要注意。回想一下对于 read 调用来说,要使用的偏移量是非常重要的。然而,对于 write 来说,这个偏移量只有在没有设置 O_APPEND 选项的文件上下文中才会非常重要。如果设置了 O_APPEND,那么这个偏移量就会被忽略,数据都会被附加到文件的末尾。否则,aio_offset 域就确定了数据在要写入的文件中的偏移量。 aio_suspend 我们可以使用 aio_suspend 函数来挂起(或阻塞)调用进程,直到异步请求完成为止,此时会产生一个信号,或者发生其他超时操作。调用者提供了一个 aiocb 引用列表,其中任何一个完成都会导致 aio_suspend 返回。 aio_suspend 的函数原型如下: int aio_suspend( const struct aiocb *const cblist[], int n, const struct timespec *timeout ); aio_suspend 的使用非常简单。我们要提供一个 aiocb 引用列表。如果任何一个完成了,这个调用就会返回 0。否则就会返回 -1,说明发生了错误。请参看清单 3。 清单 3. 使用 aio_suspend 函数阻塞异步 I/O struct aioct *cblist[MAX_LIST] /* Clear the list. */ bzero( (char *)cblist, sizeof(cblist) ); /* Load one or more references into the list */ cblist[0] = &my_aiocb; ret = aio_read( &my_aiocb ); ret = aio_suspend( cblist, MAX_LIST, NULL ); 注意,aio_suspend 的第二个参数是 cblist 中元素的个数,而不是 aiocb 引用的个数。cblist 中任何 NULL 元素都会被 aio_suspend 忽略。 如果为 aio_suspend 提供了超时,而超时情况的确发生了,那么它就会返回 -1,errno 中会包含 EAGAIN。 aio_cancel aio_cancel 函数允许我们取消对某个文件描述符执行的一个或所有 I/O 请求。其原型如下: int aio_cancel( int fd, struct aiocb *aiocbp ); 要取消一个请求,我们需要提供文件描述符和 aiocb 引用。如果这个请求被成功取消了,那么这个函数就会返回 AIO_CANCELED。如果请求完成了,这个函数就会返回 AIO_NOTCANCELED。 要取消对某个给定文件描述符的所有请求,我们需要提供这个文件的描述符,以及一个对 aiocbp 的 NULL 引用。如果所有的请求都取消了,这个函数就会返回 AIO_CANCELED;如果至少有一个请求没有被取消,那么这个函数就会返回 AIO_NOT_CANCELED;如果没有一个请求可以被取消,那么这个函数就会返回 AIO_ALLDONE。我们然后可以使用 aio_error 来验证每个 AIO 请求。如果这个请求已经被取消了,那么 aio_error 就会返回 -1,并且 errno 会被设置为 ECANCELED。 lio_listio 最后,AIO 提供了一种方法使用 lio_listio API 函数同时发起多个传输。这个函数非常重要,因为这意味着我们可以在一个系统调用(一次内核上下文切换

    02

    Linux信号列表

    ~$ kill -l 1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP 6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP 21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ 26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR 31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3 38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8 43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13 48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12 53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7 58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2 63) SIGRTMAX-1 64) SIGRTMAX

    04

    Golang信号处理和如何实现进程的优雅退出

    各操作系统的信号定义或许有些不同。下面列出了POSIX中定义的信号。 在linux中使用34-64信号用作实时系统中。 命令 man 7 signal 提供了官方的信号介绍。也可以是用kill -l来快速查看 列表中,编号为1 ~ 31的信号为传统UNIX支持的信号,是不可靠信号(非实时的),编号为32 ~ 63的信号是后来扩充的,称做可靠信号(实时信号)。不可靠信号和可靠信号的区别在于前者不支持排队,可能会造成信号丢失,而后者不会。 Linux支持的标准信号有以下一些,一个信号有多个值的是因为不同架构使用的值不一样,比如x86, ia64,ppc, s390, 有3个值的,第一个值是slpha和sparc,中间的值是 ix86, ia64, ppc, s390, arm和sh, 最后一个值是对mips的,连字符-表示这个架构是缺这个信号支持的, 第1列为信号名; 第2列为对应的信号值,需要注意的是,有些信号名对应着3个信号值,这是因为这些信号值与平台相关,将man手册中对3个信号值的说明摘出如下,the first one is usually valid for alpha and sparc, the middle one for i386, ppc and sh, and the last one for mips. 第3列为操作系统收到信号后的动作,Term表明默认动作为终止进程,Ign表明默认动作为忽略该信号,Core表明默认动作为终止进程同时输出core dump,Stop表明默认动作为停止进程。 第4列为对信号作用的注释性说明。

    04

    09.字符设备驱动

    1.写出最底层Led_Open(),Led_Write(),Led_Read()   2.如何让内核知道下面有我们写好的操作硬件的函数呢?定义一个file_operations结构体(指向Led_Open等底层函数)。使用函数regsiter_chrdev(major,”first_drv”,&first_drv_fops)注册告诉内核(通过major索引)。   3.regsiter_chrdev被谁调用?被驱动入口函数调用。first_drv_init()   4.如何知道调用first_drv_init(),还是其他的函数呢?利用宏module_init(first_drv_init)定义一个结构体,结构体中有函数指针,指向入口函数。   5.出口函数first_drv_exit。卸载驱动unregsiter_chrdev(major,”first_drv”,&first_drv_fops)。如何知道何时来调用first_drv_exit?module_init(first_drv_exit)定义一个结构体,结构体中有函数指针,指向入口函数。

    02
    领券