Leo 的内核精简笔记(2) 进程模型

来源:互联网 发布:韶关市仁化县网络问政 编辑:程序博客网 时间:2024/06/13 03:33
 

Leo 的2.6内核笔记(2) 进程

本文是《linux 内核编程》即《The Linux kernel Primer-A top down approach for x86 and PowerPC Architectures》 简称LKP的笔记 如果发现有错误或者有意见请告诉我 hide1713 AT gmail DOT com


进程

进程表示一个活的程序执行单位.放在硬盘里的程序是死的.只有当程序被加载进内存成为进程,这个程序才是活的.关于进程有很多内容好说.下面我将先介绍一点基本概念.然后从进程的状态开始讲.

分时系统

知道一点计算机历史的人都知道,早期的操作系统是批处理操作系统.任务一个接一个的执行.比如我有一个任务是整理磁盘 碎片,预计要花2小时 .那我就必须等着碎片整理完成.才能打开realplayer看电影.在执行过程中每个进程都是完全占用cpu.随着OS的发展.出现了分时操作系统.这 样的系统把cpu时间分别给不同的进程使用.比如磁盘整理程序用0.2秒,realplayer用0.2秒.由于这些进程切换得很快.让人有了一种所有程 序都在同时运行的错觉.每个进程都被分到一定长度的时间片.当进程执行完自己的时间片后就要让出cpu给其他进程执行.

用户态 内核态

进程运行在用户态,内核运行在内核态.为什么要分成这两个态呢?因为操作系统要想稳定,必须防止运行在上面的程序乱读 乱写.用户态的程序要想做一些可能会影响系统的操作,必须通过系统调用,由操作系统检查后方能执行.用户态的程序是不能改变内核程序的.所以保护内核不被 恶意或无意的修改.

进程上下文 context

所谓上下文就是进程当前执行的状态,程序被中断时,先要保存当前进程的所有寄存器,文件,程序计数器等等信息.这样才能当进程继续执行时 恢复中断前的状态

进程的状态有下面几种:

准备
进程创建好了或者用完了时间片.在等待被执行.
运行
在cpu上运行
等待/堵塞
被中断或者等待某些事件(比如用户输入)
僵死
已经执行完成.但是父进程还没调用wait4()让他真正死亡

task_struct

task_struct是描述一个进程的数据结构,非常重要.这个数据结构在 include/linux/sched.h 中声明.LKP书中对这部分已经有了很好的介绍.下面的程序扩展了原书中这章最后的代码.显示current的数据结构(当前的current就是 insmod).并遍历所有的进程.这个例子还是用原来的makefile编译.

//hello world from leo
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/tty.h>
#include <linux/list.h>//和List相关操作的宏
MODULE_LICENSE("GPL");

void tty_msg(struct tty_struct *,char *);

static int __init my_init(void)
{
char *msg="Hello, This is Leo module speaking/n";
pid_t user_pid,parent_pid;
struct task_struct * ts;
user_pid=current->pid;
printk("current pid is %d",user_pid);
parent_pid=current->parent->pid;
printk("/nparent pid is %d/n",parent_pid);
printk("hello from kernel/n");
tty_msg(current->signal->tty,msg);
switch (current->state)
{
case TASK_RUNNING:
printk("task_running/n");
break;
case TASK_INTERRUPTIBLE:
printk("task_interruptible/n");
break;
case TASK_UNINTERRUPTIBLE:
printk("task_uninterruptible /n");
break;
case TASK_STOPPED:
printk("task_stopped/n");
break;
default:
printk("unknown_state/n");
}
printk("prio is %d and static prio is %d /n",current->prio,current->static_prio);
printk("time slice is %d /n",current->time_slice);
printk("Print all process in tasks/n");

list_for_each_entry(ts,&current->tasks,tasks){
printk("hello this is process %s %d speaking/n",ts->comm,ts->pid);
}
//for_each_process(ts) //做同样的事的另外一个宏
// printk("hello this is process %s %d speaking/n",ts->comm,ts->pid);
printk("end init()/n");
return 0;
}

static void __exit my_exit(void)
{
printk("bye kernel/n");
}

module_init(my_init);
module_exit(my_exit);
void tty_msg(struct tty_struct *tty, char *msg)
{
if(tty &&tty->driver->write)
tty->driver->write(tty,msg,strlen(msg));
return;
}