您的位置:首页 > 运维架构 > Linux

Linux内核学习之四--进程、进程调度、系统调用、proc文件系统和内核异常分析

2012-10-06 08:40 661 查看
一、Linux进程控制(内核角度)

1》定义

程序:程序是存放在磁盘上的一系列代码和数据的可执行映像,是一个静止的实体。

进程:是一个执行中的程序,它是动态的实体。

2》进程四要素

a)有一段程序供其执行。

b)有进程专用的内核空间堆栈。

c)在内核中有一个task_struct数据结构。PCB:process control block,即task_struct

d)有独立的用户空间堆栈。

有共享的--用户线程 完全没有用户空间--内核线程

3》进程描述

Linux中进程和线程都用struct task_struct结构表示

a)pid_t pid:进程号

volatile long state:进程状态

*TASK_RUNNING:就绪和执行都是该状态

*TASK_INTERRUPTIBLE:可中断的阻塞,即可以被信号唤醒

*TASK_UNINTERRUPTIBLE 不可以被信号唤醒 但是可以通过函数强制唤醒

TASK_STOPPED:暂时中止,收到SIGSTOP SIGTSTP即为该状态,其它进程通过signal或中断唤醒。

TASK_KILLABLE:阻塞的一种,类似于TASK_UNINTERRUPTIBLE,但是可以被SIGKILL唤醒

TASK_TRACED:正处于被调试的进程 gdb 单步停下来时即该状态

TASK_DEAD:进程退出时(调用do_exit),state字段被设置为该状态

b)int exit_state 进程退出时的状态

EXIT_ZOMBILE僵死进程,表示进程的执行被终止,但是父进程还没有发布waitpid()系统调用来收集有关死亡

的进程信息。【父进程 通知 内核 回收资源】

EXIT_DEAD僵死撤销状态

c)struct mm_struct *mm进程用户空间描述指针,内核线程该项为空

unsigned int policy 该进程的调度策略

d)int prio等等

task_struct位置:

1》2.4

两个连续物理页面的底部1KB,内核空间堆栈7KB,大的数组会导致栈溢出

2》2.6

thread_info structure包含一个task指针,指向task_struct结构

当前运行的进程

current指针指向当前正在运行的进程的task_struct

进程创建:

用户空间 内 核 空 间

fork()----sys_fork()-----do_fork()

vfork()---sys_vfork()----do_fork()

sys_clone()----do_fork()

kernel_thread--do_fork()

copy_process---do_fork()

销毁

exit()---sys_exit--------do_exit()

fatal signals---do_exit()

二、Linux进程调度

(较复杂 中等了解)

从就绪的进程中选出最适合的一个来执行

知识点:调度策略 调度时机 调度步骤

1》调度策略:最合适即为策略

SCHED_NORMAL(SCHED_OTHER)

SCHED_FIFO

SCHED_RR

SCHED_BATCH:

SCHED_IDLE

可以划分为两大类:

CFS调度类:在kernel/sched_fair.c中实现,用于SCHED_NORMAL SCHED_NORMAL SCHED_BATCH

CFS:Complete Fire Scheduler 完全公平调度类

实时调度类 在kernel/sched_rt.c中实现 用于SCHED_RR和SCHED_FIFO

一个进程只能遵循一个调度策略,应用程序创建时默认SCHED_NORMAL,不过是可以修改的

调度类:struct sched_class,其中包含一个重要的函数指针pick_next_task,选择下一个要运行的进程

2》调度时机

a)主动式 直接调用schedule(),需要等待资源而暂时停止运行时,会把状态置为挂起,主动请求调度 让出cpu

主动放弃cpu例子:

current->state = TASK_INTERRUPTIBLE;

schedule();

b)被动式(抢占)

用户抢占 2.4 2.6支持

内核抢占 2.6支持

用户抢占发生在:

*从系统调用返回用户空间

*从中断处理程序返回用户空间

内核即将返回用户空间的时候,如果need_resched标志被设置,会导致schedule()被调用,此时就会发生用户

抢占

某些特例下不允许内核抢占:

中断处理 中断上下文处理 自选所 读写锁 正在执行调度

内核使用了preempt_count 内核抢占计数器 不能被抢占时加1,从以上状态退出时减1

内核抢占发生在:

*中断处理程序完成 返回内核空间之前

*当内核代码再一次具有可抢占性的时候 如解锁及时能软中断

调度标志:need_resched

2》调度步骤

a.清理当前运行中的进程

b.选择下一个要运行的进程 pick_next_task 重要环节

c.设置新进程的运行环境

d.进程上下文切换

分析pick_next_task

三、Linux系统调用

read write close open 等等

系统调用:Linux内核中设置了一组用于实现各种系统功能的子程序。

系统调用和普通函数的区别:

系统调用:实现在内核空间,运行于内核态

普通函数:由函数库或用户自己提供,运行于用户态

Linux库函数对系统调用进行了一定的封装,这些库函数于系统调用关系密切

系统调用个数:

arch/arm/include/asm/unistd.h

系统调用工作原理

使用系统调用时,进行现用适当的值填充寄存器,然后调用一个特殊的指令,

这个指令会让用户程序跳转到一个事先定义好的内核中的一个位置:

x86 0x80

ARM SWI

ENTYR(vector_swi)<arch/arm/kernel/enty-common.S>

数字和sys_call_table对比 找出相应的函数

事先系统调用的三个步骤:

1>添加新的内核函数

2>更新unistd.h

3>根据系统调用表 更新 call.S

四、Proc文件系统

Proc文件系统是一种在用户态检查内核状态的机制。proc文件系统提供了一条途径。

/proc/目录下面有诸多文件

例如 内核中断发生了多少次

a)每个文件都规定了严格的权限

b)文本编辑程序查看

c)不仅有文件 也可以有子目录

d)可以自己编写程序添加一个/proc/下的文件

e)文件的内容都是动态创建的,并不存在于磁盘上

数据结构

struct proc_dir_entry

read

write

a)使用create_proc_entry函数创建proc文件

b)proc_mkdir创建proc目录下的目录

c)使用remove_proc_entry删除文件或目录

读写回调函数:

read_proc

write_proc

proc文件 不去读它的时候 里面没有内容,只有在去读的时候,才会有东西

显示什么 在read函数中控制

五、内核异常分析

Oops信息

1》查看错误原因

2》调用栈(对照反汇编代码)

3》寄存器
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐