linux异步命令 linux aio 异步写

在Linux中我还是理解不了同步和异步,求解释

打个比方,你现在要做两件事,一件事是烧水,一件事是晾衣服。所谓的同步就是指:你必须等水烧开了再去晾衣服。所谓的异步就是指在烧水的过程中,你完全可以再去晾衣服。所以,引入异步机制其实就是为了提高效率。当然,有的时候,如果两件事之间有依赖性,那么就是无法异步的,比如烧水和喝水,这两件事是没法异步去做的。

宁海网站制作公司哪家好,找创新互联建站!从网页设计、网站建设、微信开发、APP开发、响应式网站建设等网站项目制作,到程序开发,运营维护。创新互联建站于2013年成立到现在10年的时间,我们拥有了丰富的建站经验和运维经验,来保证我们的工作的顺利进行。专注于网站建设就选创新互联建站

Linux异步IO

Linux中最常用的IO模型是同步IO,在这个模型中,当请求发出之后,应用程序就会阻塞,直到请求满足条件为止。这是一种很好的解决方案,调用应用程序在等待IO完成的时候不需要占用CPU,但是在很多场景中,IO请求可能需要和CPU消耗交叠,以充分利用CPU和IO提高吞吐率。

下图描绘了异步IO的时序,应用程序发起IO操作后,直接开始执行,并不等待IO结束,它要么过一段时间来查询之前的IO请求完成情况,要么IO请求完成了会自动被调用与IO完成绑定的回调函数。

Linux的AIO有多种实现,其中一种实现是在用户空间的glibc库中实现的,本质上是借用了多线程模型,用开启的新的线程以同步的方式做IO,新的AIO辅助线程与发起AIO的线程以pthread_cond_signal()的形式进行线程间的同步,glibc的AIO主要包含以下函数:

1、aio_read()

aio_read()函数请求对一个有效的文件描述符进行异步读操作。这个文件描述符可以代表一个文件、套接字,甚至管道,aio_read()函数原型如下:

aio_read()函数在请求进行排队之后就会立即返回(尽管读操作并未完成),如果执行成功就返回0,如果出现错误就返回-1。参数aiocb(AIO I/O Control Block)结构体包含了传输的所有信息,以及为AIO操作准备的用户空间缓冲区。在产生IO完成通知时,aiocb结构就被用来唯一标识所完成的IO操作。

2.aio_write()

aio_write()函数用来请求一个异步写操作。函数原型如下:

aio_write()函数会立即返回,并且它的请求以及被排队(成功时返回值为0,失败时返回值为-1)

3.aio_error()

aio_error()函数被用来确定请求的状态,其原型如下:

该函数的返回:

4.aio_return()

异步IO和同步阻塞IO方式之间有一个区别就是不能立即访问函数的返回状态,因为异步IO没有阻塞在read()调用上。在标准的同步阻塞read()调用中,返回状态是在该函数返回时提供的。

但是在异步IO中,我们要用aio_return()函数,原型如下:

只有在aio_error()调用确定请求已经完成(可能成功、也可能发生了错误)之后,才会调用这个函数,aio_return()的返回值就等价于同步情况中read()或者write系统调用的返回值。

5.aio_suspend()

用户可以用该函数阻塞调用进程,直到异步请求完成为止,调用者提供了一个aiocb引用列表,其中任何一个完成都会导致aio_suspend()返回。函数原型如下:

6.aio_cancel()

该函数允许用户取消对某个文件描述符执行的一个或所以IO请求。

要取消一个请求,用户需要提供文件描述符和aiocb指针,如果这个请求被成功取消了,那么这个函数就会返回AIO_CANCELED。如果请求完成了,就会返回AIO_NOTCANCELED。

7.lio_listio()

lio_listio()函数可用于同时发起多个传输。这个函数非常重要,它使得用户可以在一个系统调用中启动大量的IO操作,原型如下:

mode参数可以是LIO_WAIT或者是LIO_NOWAIT。LIO_WAIT会阻塞这个调用,直到所有的IO都返回为止,若是LIO_NOWAIT模型,在IO操作完成排队之后,该函数就会返回。list是一个aiocb的列表,最大元素的个数是由nent定义的。如果list的元素为null,lio_listio()会将其忽略。

如何查看linux是否开启异步IO

查看linux是否开启异步IO命令如下:

[DATA@localhost ~]$ cat /proc/slabinfo | grep kio

kioctx 37 140 384 10 1 : tunables 54 27 8 : slabdata 14 14 0

kiocb 0 0 256 15 1 : tunables 120 60 8 : slabdata 0 0 0

返回结果中kiocp对应的前两项为0,说明系统中没有使用异步io。

linux异步通知之驱动层怎么释放SIGUSR1/SIGUSR2

首先,Linux中的信号可以通过kill -l命令获取,

如上图所示,编号为1 ~ 31的信号为传统UNIX支持的信号,是不可靠信号(非实时的),编号为32 ~ 63的信号是后来扩充的,称做可靠信号(实时信号)。不可靠信号和可靠信号的区别在于前者不支持排队,可能会造成信号丢失,而后者不会。

其次,SIGUSR1 ,这是留给用户使用的信号。一般在编程中使用。举例说明:sigqueue向本进程发送数据的信号,C语言代码如下 :

#include stdio.h

#include string.h

#include stdlib.h

#include signal.h

#include unistd.h

void myhandler(int signo,siginfo_t *si,void *ucontext);

int main(){

union sigval val;//定义一个携带数据的共用体

struct sigaction oldact,act;

act.sa_sigaction=myhandler;

act.sa_flags=SA_SIGINFO;//表示使用sa_sigaction指示的函数,处理完恢复默认,不阻塞处理过程中到达下在被处理的信号

//注册信号处理函数

sigaction(SIGUSR1,act,oldact);

char data[100];

int num=0;

while(num10){

sleep(2);

printf("等待SIGUSR1信号的到来\n");

sprintf(data,"%d",num++);

val.sival_ptr=data;

sigqueue(getpid(),SIGUSR1,val);//向本进程发送一个信号

}

}

void myhandler(int signo,siginfo_t *si,void *ucontext){

printf("已经收到SIGUSR1信号\n");

printf("%s\n",(char*)(si-si_ptr));

}


新闻标题:linux异步命令 linux aio 异步写
分享地址:http://pwwzsj.com/article/dosjeds.html