iotop源码分析二

import ctypes
import fnmatch
import os
import platform
import time

IOPRIO_GET_ARCH_SYSCALL = [
    (‘alpha‘,       ‘*‘,  443),
    (‘i*86‘,        ‘*‘,  290),
    (‘ia64*‘,       ‘*‘, 1275),
    (‘ppc*‘,        ‘*‘,  274),
    (‘s390*‘,       ‘*‘,  283),
    (‘sparc*‘,      ‘*‘,  218),
    (‘sh*‘,         ‘*‘,  289),
    (‘x86_64*‘, ‘32bit‘,  290),
    (‘x86_64*‘, ‘64bit‘,  252),
]

IOPRIO_SET_ARCH_SYSCALL = [
    (‘alpha‘,       ‘*‘,  442),
    (‘i*86‘,        ‘*‘,  289),
    (‘ia64*‘,       ‘*‘, 1274),
    (‘ppc*‘,        ‘*‘,  273),
    (‘s390*‘,       ‘*‘,  282),
    (‘sparc*‘,      ‘*‘,  196),
    (‘sh*‘,         ‘*‘,  288),
    (‘x86_64*‘,  ‘32bit‘, 289),
    (‘x86_64*‘,  ‘64bit‘, 251),
]

#查看本机的CPU架构类型和处理器位数
def find_ioprio_syscall_number(syscall_list):
    arch = os.uname()[4]
    bits = platform.architecture()[0]
    for candidate_arch, candidate_bits, syscall_nr in syscall_list:
        if fnmatch.fnmatch(arch,candidate_arch) and fnmatch.fnmatch(bits,candidate_bits):
           return syscall_nr
           
class IoprioSetError(Exception):
    def __init__(self,err):
        try:
          self.err = os.strerror(err)
        except TypeError:
          self.err = err

__NR_ioprio_get = find_ioprio_syscall_number(IOPRIO_GET_ARCH_SYSCALL)
__NR_ioprio_set = find_ioprio_syscall_number(IOPRIO_SET_ARCH_SYSCALL)

#print __NR_ioprio_get,__NR_ioprio_set
try:
   ctypes_handle = ctypes.CDLL(None, user_errno=True)
except TypeError:
   ctypes_handle = ctypes.CDLL(None)

syscall = ctypes_handle.syscall

#定义几种I/O调度类别
PRIORITY_CLASS = [None, ‘rt‘, ‘be‘, ‘idle‘]

IOPRIO_WHO_PROCESS = 1
IOPRIO_CLASS_SHIFT = 13
IOPRIO_PRIO_MASK = (1 << IOPRIO_CLASS_SHIFT) -1

def ioprio_value(ioprio_class,ioprio_data):
    try:
        ioprio_class = PRIORITY_CLASS.index(ioprio_class)
    except ValueError:
        ioprio_class = PRIORITY_CLASS.index(None)
    return (ioprio_class << IOPRIO_CLASS_SHIFT) | ioprio_data

def ioprio_class(ioprio):
    return PRIORITY_CLASS[ioprio >> IOPRIO_CLASS_SHIFT]

def ioprio_data(ioprio):
    return ioprio & IOPRIO_PRIO_MASK

sched_getscheduler = ctypes_handle.sched_getscheduler
SCHED_OTHER, SCHED_FIFO, SCHED_RR, SCHED_BATCH, SCHED_ISO, SCHED_IDLE = range(6)

getpriority = ctypes_handle.getpriority
PRIO_PROCESS = 0

#根据PID获得I/O调度类别和优先级
def get_ioprio_from_sched(pid):
    scheduler = sched_getscheduler(pid)
    nice = getpriority(PRIO_PROCESS,pid)
    ioprio_nice = (nice + 20)/5

    if scheduler in (SCHED_FIFO,SCHED_RR):
       return ‘rt/%d‘ % ioprio_nice
    elif scheduler == SCHED_IDLE:
       return ‘idle‘
    else:
       return ‘be/%d‘ % ioprio_nice

       
def get(pid):
    if __NR_ioprio_get is None:
       return ‘?sys‘

    ioprio = syscall(__NR_ioprio_get, IOPRIO_WHO_PROCESS, pid)
    if ioprio < 0:
       return ‘?err‘

    prio_class = ioprio_class(ioprio)
    if not prio_class:
       return get_ioprio_from_sched(pid)

    if prio_class == ‘idle‘:
       return prio_class
    return ‘%s/%d‘ % (prio_class, ioprio_data(ioprio))

def set_ioprio(which, who, ioprio_class, ioprio_data):
    if __NR_ioprio_set is None:
       raise IoprioSetError(‘No ioprio_set syscall found‘)

    ioprio_val = ioprio_value(ioprio_class,ioprio_data)
    ret = syscall(__NR_ioprio_set, which, who, ioprio_val, use_errno=True)
    if ret < 0:
       try:
            err = ctypes.get_errno()
       except AttributeError:
            err = ‘Unknown error (errno support not available before Python2.6)‘
            raise IoprioSetError(err)

def sort_key(key):
    if key[0] == ‘?‘:
       return -ord(key[1])

    if ‘/‘ in key:
       if key.startswith(‘rt/‘):
          shift = 0
       elif key.startswith(‘be/‘):
          shift = 1
       prio = int(key.split(‘/‘)[1])

    elif key == ‘idle‘:
          shift =2
          prio = 0

    return (1 << (shift * IOPRIO_CLASS_SHIFT)) + prio

def to_class_and_data(ioprio_str):
    if ‘/‘ in ioprio_str:
       split = ioprio_str.split(‘/‘)
       return (split[0], int(split[1]))
    elif ioprio_str == ‘idle‘:
       return (‘idle‘,0)
    return (None,None)

#如果指定PID,则获取指定PID的I/O调度类别和优先级,不指定就获取当前进程的I/O调度类别和优先级
if __name__ == ‘__main__‘:
    import sys
    if len(sys.argv) == 2:
       pid = int(sys.argv[1])
    else:
       pid = os.getpid()
    print ‘pid:‘, pid
    print ‘ioprio:‘, get(pid)

输出结果:

$ python ioprio.py 
pid: 11628
ioprio: be/4
$ python ioprio.py 32600
pid: 32600
ioprio: be/4

这个程序涉及到Linux的I/O调度和进程调度的知识

时间: 2024-11-10 07:54:40

iotop源码分析二的相关文章

netty 源码分析二

以服务端启动,接收客户端连接整个过程为例分析, 简略分为 五个过程: 1.NioServerSocketChannel 管道生成, 2.NioServerSocketChannel 管道完成初始化, 3.NioServerSocketChannel注册至Selector选择器, 4.NioServerSocketChannel管道绑定到指定端口,启动服务 5.NioServerSocketChannel接受客户端的连接,进行相应IO操作 Ps:netty内部过程远比这复杂,简略记录下方便以后回忆

[Android]Volley源码分析(二)Cache

Cache作为Volley最为核心的一部分,Volley花了重彩来实现它.本章我们顺着Volley的源码思路往下,来看下Volley对Cache的处理逻辑. 我们回想一下昨天的简单代码,我们的入口是从构造一个Request队列开始的,而我们并不直接调用new来构造,而是将控制权反转给Volley这个静态工厂来构造. com.android.volley.toolbox.Volley: public static RequestQueue newRequestQueue(Context conte

哇!板球 源码分析二

游戏主页面布局 创建屏下Score标签 pLabel = CCLabelTTF::create("Score", "Arial", TITLE_FONT_SIZE); //分数标签 //设置标签字体的颜色 pLabel->setColor (ccc3(0, 0, 0)); //设置文本标签的位置 pLabel->setPosition ( ccp ( SCORE_X, //X坐标 SCORE_Y //Y坐标 ) ); //将文本标签添加到布景中 this

baksmali和smali源码分析(二)

这一节,主要介绍一下 baksmali代码的框架. 我们经常在反编译android apk包的时候使用apktool这个工具,其实本身这个工具里面对于dex文件解析和重新生成就是使用的baksmali 和smali这两个jar包其中 baksmali是将 dex文件转换成便于阅读的smali文件的,具体使用命令如下:java -jar baksmali.jar classes.dex -o myout其中myout是输出的文件夹 而smali是将smali文件重新生成回 dex文件的具体使用的命

【梦幻连连连】源码分析(二)

转载请注明出处:http://blog.csdn.net/oyangyufu/article/details/24736711 GameLayer场景界面效果: 源码分析: GameLayer场景初始化,主要是初始化加载界面及背景音乐 bool GameLayer::init() { float dt=0.0f; if ( !CCLayerColor::initWithColor(ccc4(255, 255, 255, 255))) { return false; } this->initLoa

[Android]Fragment源码分析(二) 状态

我们上一讲,抛出来一个问题,就是当Activity的onCreateView的时候,是如何构造Fragment中的View参数.要回答这个问题我们先要了解Fragment的状态,这是Fragment管理中非常重要的一环.我们先来看一下FragmentActivity提供的一些核心回调: @Override protected void onCreate(Bundle savedInstanceState) { mFragments.attachActivity(this, mContainer,

JAVA Collection 源码分析(二)之SubList

昨天我们分析了ArrayList的源码,我们可以看到,在其中还有一个类,名为SubList,其继承了AbstractList. // AbstractList类型的引用,所有继承了AbstractList都可以传进来 private final AbstractList<E> parent; // 这个是其实就是parent的偏移量,从parent中的第几个元素开始的 private final int parentOffset; private final int offset; int s

Tomcat源码分析二:先看看Tomcat的整体架构

Tomcat源码分析二:先看看Tomcat的整体架构 Tomcat架构图 我们先来看一张比较经典的Tomcat架构图: 从这张图中,我们可以看出Tomcat中含有Server.Service.Connector.Container等组件,接下来我们一起去大致的看看这些组件的作用和他们之间的相互联系.在这之前,我们先补充一个知识点,也就是Tomcat它实现的功能点是什么呢?通过查找一些资料,这里参考下极客时间<深入拆解Tomcat_Jetty>中的总结,即Tomcat 要实现 2 个核心功能:

Volley源码分析二

在前两天我发布的文章:Volley源码分析一 中我较为详细的分析了Volley,今天继续,这篇文章会讲一些上一篇没有提到的比较细节的点,以及对于Volley源码中一些可以优化的实现的一些思考 ByteArrayPool的分析 byte[] 的回收池,用于 byte[] 的回收再利用,减少了内存的分配和回收.主要通过一个元素长度从小到大排序的ArrayList作为 byte[] 的缓存,另有一个按使用时间先后排序的ArrayList属性用于缓存满时清理元素. public synchronized