linux io.h(Linux修改时间)

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活动状况 00 Hey,Linux

您好,很高兴为您解答。服务器cpu使用率不高,load比较高,所以要查看一下IO。硬盘IO可以通过命令vmstat或iostat获得(也可以用yum安装dstat获得),网络IO可以用iftop命令获取。但是不知道那个进程使用硬盘IO比较高,通过查找没有找到相关命令,只好自己写个脚本进行统计处理。本脚本在CentOS6下(kernel2.6以上)python2.6测试通过。直接运行脚本,默认情况下收集3秒钟数据,显示读写最高的前三个进程。如用参数可以使用命令“pythonfhip.py453”,第一个数位每次收集读写数据的间隔秒数,第二个数是打印出读写最多的n个进程,第三个为运行脚本的次数。因为参数部分写的比较简单那,所以用参数必须3个全写。。#!/bin/python#-*-coding:utf-8-*-#Filename:ind_high_io_process#Revision:1.0#Date:2013-3-8#Author:simonzhang#web:###ENDINITINFOimportosimportreimportsysimporttimefromstringimportstrip####sys_proc_path='/proc/'re_find_process_number='^\d+$'#####通过/proc/$pid/io获取读写信息####defcollect_info():_tmp={}re_find_process_dir=re.compile(re_find_process_number)foriinos.listdir(sys_proc_path):ifre_find_process_dir.search(i):#获得进程名process_name=open("%s%s/stat"%(sys_proc_path,i),"rb").read().split("")[1]#读取io信息rw_io=open("%s%s/io"%(sys_proc_path,i),"rb").readlines()for_infoinrw_io:cut_info=strip(_info).split(':')ifstrip(cut_info[0])=="read_bytes":read_io=int(strip(cut_info[1]))ifstrip(cut_info[0])=="write_bytes":write_io=int(strip(cut_info[1]))_tmp[i]={"name":process_name,"read_bytes":read_io,"write_bytes":write_io}return_tmpdefmain(_sleep_time,_list_num):_sort_read_dict={}_sort_write_dict={}#获取系统读写数据process_info_list_frist=collect_info()time.sleep(_sleep_time)process_info_list_second=collect_info()#将读数据和写数据进行分组,写入两个字典中forloopinprocess_info_list_second.keys():second_read_v=process_info_list_second[loop]["read_bytes"]second_write_v=process_info_list_second[loop]["write_bytes"]try:frist_read_v=process_info_list_frist[loop]["read_bytes"]except:frist_read_v=0try:frist_write_v=process_info_list_frist[loop]["write_bytes"]except:frist_write_v=0#计算第二次获得数据域第一次获得数据的差_sort_read_dict[loop]=second_read_v-frist_read_v_sort_write_dict[loop]=second_write_v-frist_write_v#将读写数据进行排序sort_read_dict=sorted(_sort_read_dict.items(),key=lambda_sort_read_dict:_sort_read_dict[1],reverse=True)sort_write_dict=sorted(_sort_write_dict.items(),key=lambda_sort_write_dict:_sort_write_dict[1],reverse=True)#打印统计结果print"pidprocessread(bytes)pidprocesswrite(btyes)"for_numinrange(_list_num):read_pid=sort_read_dict[_num][0]write_pid=sort_write_dict[_num][0]res="%s"%read_pidres+=""*(8-len(read_pid))+process_info_list_second[read_pid]["name"]res+=""*(12-len(process_info_list_second[read_pid]["name"]))+"%s"%sort_read_dict[_num][1]res+=""*(12-len("%s"%sort_read_dict[_num][1]))+write_pidres+=""*(8-len(write_pid))+process_info_list_second[write_pid]["name"]res+=""*(12-len("%s"%process_info_list_second[write_pid]["name"]))+"%s"%sort_write_dict[_num][1]printresprint"\n"*1if__name__=='__main__':try:_sleep_time=sys.argv[1]except:_sleep_time=3try:_num=sys.argv[2]except:_num=3try:loop=sys.argv[3]except:loop=1foriinrange(int(loop)):main(int(_sleep_time),int(_num))如若满意,请点击【采纳答案】,如若还有问题,请点击【追问】希望我的回答对您有所帮助,望采纳!~O(∩_∩)O~

Linux驱动开发头文件剖析(二十七):<linux/wait.h>

wait.h》主要用于进程同步和等待队列的管理,提供宏和函数实现内核中等待队列机制,支持进程在条件满足前进入睡眠状态,被唤醒后继续执行。这一机制广泛应用于并发、同步和事件等待场景,是驱动开发和内核模块编写中常见工具。

PS1:睡眠与等待在特定情况下等同,需谨慎辨识。

PS2:宏或函数功能通常从名称可大致推断,具体用法查阅文档。

wait_queue_entry_t类型是 wait_queue_entry的别名,wait_queue_func_t指向四个参数、返回 int的函数指针。wait_queue_entry结构体定义了等待队列中的每个节点,包括进程状态、唤醒函数等字段。

通用唤醒函数用于尝试唤醒等待队列中的进程。

该函数实现于相应位置。

定义了用于描述等待队列项状态和行为的标志位。

wait_queue_head_t是 struct wait_queue_head的别名,用于实现等待队列机制,包含自旋锁和链表头,保护和管理等待队列。

struct task_struct的声明在 wait.h内,具体实现位于相应位置,与调度相关讨论时会涉及。

__WAITQUEUE_INITIALIZER初始化 wait_queue_entry结构体,根据给定的 name和 task,将其 private指针指向进程结构体 tsk,并设置默认唤醒函数和空的前后指针。

DECLARE_WAITQUEUE是 __WAITQUEUE_INITIALIZER的简化封装,得到 wait_queue_entry变量。

__WAIT_QUEUE_HEAD_INITIALIZER初始化等待队列头,设置锁字段和队列头字段。

DECLARE_WAIT_QUEUE_HEAD是 __WAIT_QUEUE_HEAD_INITIALIZER的简化封装。

__init_waitqueue_head初始化 wq_head的各项属性。

init_waitqueue_head在 __init_waitqueue_head的基础上增加用于锁调试的变量。

__init_waitqueue_head_onstack初始化等待队列头,用于栈上分配。

DECLARE_WAITQUEUE_HEAD_ONSTACK是 __init_waitqueue_head_onstack的简化封装。

init_waitqueue_entry初始化等待队列节点,将唤醒函数设置为默认唤醒函数。

init_waitqueue_func_entry与 init_waitqueue_entry类似,通过给定的唤醒函数进行进程唤醒。

waitqueue_active无锁地检查等待队列是否为空,返回布尔值指示等待队列状态。

PS:使用时需小心数据竞争。

判断等待队列中是否有唯一等待进程。

检查给定等待队列中有无等待进程。

这三个函数与等待队列机制相关,用于添加、移除等待队列中的等待项。

__add_wait_queue将等待项添加到等待队列中,通常为头部。

__add_wait_queue_exclusive通过设置独占标志将等待项添加,确保独占等待。

__add_wait_queue_entry_tail将等待项添加到队列尾部。

__add_wait_queue_entry_tail_exclusive与 __add_wait_queue_entry_tail类似,设置独占标志。

__remove_wait_queue从等待队列中移除等待项。

这些宏用于非阻塞机制下唤醒等待队列中的任务,实现 I/O多路复用等功能。

wake_up_pollfree通知等待队列即将被销毁,用于非阻塞轮询处理。

___wait_cond_timeout检查条件并修改返回值。

___wait_is_interruptible检查任务状态是否可中断。

init_wait_entry初始化等待队列条目。

___wait_event实现等待队列机制,支持不同等待策略。

__wait_event、wait_event、might_sleep、__io_wait_event、__wait_event_freezable、__wait_event_timeout、__wait_event_exclusive_cmd、__wait_event_interruptible、__wait_event_killable、__wait_event_freezable_exclusive等宏,用于实现各种等待队列操作。

__wait_event_interruptible_timeout、__wait_event_hrtimeout、wait_event_interruptible_hrtimeout等宏,提供超时等待功能。

__wait_event_idle、wait_event_idle_exclusive、wait_event_idle_timeout、__wait_event_idle_exclusive_timeout等宏,支持 TASK_IDLE状态下等待。

do_wait_intr、do_wait_intr_irq提供等待队列支持,并允许在等待时被中断。

__wait_event_killable、__wait_event_killable_exclusive宏用于 TASK_KILLABLE状态下的等待。

__wait_event_killable_timeout、wait_event_killable_timeout宏提供超时等待功能。

这些函数和宏用于处理等待队列,支持线程在条件满足前进入睡眠状态,直到被唤醒。

init_wait初始化已经存在的 wait_queue_entry结构体。

try_invoke_on_locked_down_task尝试在已锁定任务上调用函数,确保操作安全。

阅读剩余
THE END