进程调度:

创建进程时,进程调度类的初始化在函数sched_init()进行
void sched_init(void) { int i; struct desc_struct * p; if (sizeof(struct
sigaction) != 16) panic("Struct sigaction MUST be 16 bytes"); //设置内核的局部状态
描述符和程序状态段 set_tss_desc(gdt+FIRST_TSS_ENTRY,&(init_task.task.tss));
set_ldt_desc(gdt+FIRST_LDT_ENTRY,&(init_task.task.ldt)); //偏移量 p =
gdt+2+FIRST_TSS_ENTRY; //清空整个全局的task struct 结构体指针数组 for(i=1;i<NR_TASKS;i++) {
task[i] = NULL; //清空task列表 //清空GDT p->a=p->b=0; p++; p->a=p->b=0; p++; } /*
Clear NT, so that we won't have troubles with that later on */ __asm__("pushfl
; andl $0xffffbfff,(%esp) ; popfl"); //设置cms ltr(0); lldt(0);
outb_p(0x36,0x43); /* binary, mode 3, LSB/MSB, ch 0 */ outb_p(LATCH & 0xff ,
0x40); /* LSB */ outb(LATCH >> 8 , 0x40); /* MSB */ //开启系统时钟中断
set_intr_gate(0x20,&timer_interrupt); outb(inb_p(0x21)&~0x01,0x21); //开启系统调用
设置中断函数 set_system_gate(0x80,&system_call); }

相当于把进程看成一个一个链表结点。

进程创建:

* 首先我们先创建0号进程,0号进程是所有进程的父进程。(main.c/init())               
void init(void) { int pid,i; //运行setup.s程序,进行配置 //获取由setup程序进行解析的参数
setup((void *) &drive_info); //open标准输入的文件句柄 (void) open("/dev/tty0",O_RDWR,0);
//打开标准输入控制台 (void) dup(0); //打开标准输出控制台 (void) dup(0); //打开标准错误控制台 //make
mkdir("/proc",755); mknod("/proc/sysinfo", S_IFPROC,8 ); printf("%d buffers =
%d bytes buffer space\n\r",NR_BUFFERS, NR_BUFFERS*BLOCK_SIZE); printf("Free
mem: %d bytes\n\r",memory_end-main_memory_start); //创建1号进程 if (!(pid=fork())) {
close(0); if (open("/etc/rc",O_RDONLY,0)) _exit(1);
execve("/bin/sh",argv_rc,envp_rc); _exit(2); }
   init()函数概述:

            1.打开标准输入 输出 错误的控制台句柄

            2.创建1号进程,如果创建成功,则在一号进程中首先打开了  "/etc/rc"文件 (配置文件)执行SHELL程序 "/bin/sh"

    注意:0号进程是不可能结束的,它会在没有其他进程调用的时候,只执行for(;;) pause();

* 在tack链表中找一个进程空位存放当前进程  (fork.c) ,返回一个进程号
int find_empty_process(void) { int i; repeat: if ((++last_pid)<0) last_pid=1;
for(i=0 ; i<NR_TASKS ; i++) if (task[i] && task[i]->pid == last_pid) goto
repeat; for(i=1 ; i<NR_TASKS ; i++) if (!task[i]) return i; return -EAGAIN; }
* 创建一个子进程的task_struct结构体
//为task_struct分配一片内存 p = (struct task_struct *) get_free_page(); if (!p)
return -EAGAIN;
* 将当前的子进程放入到整体进程链表中

         task[nr] = p;

* 设置当前的task_struct结构体//设置分配好并且添加到全局task数组中的task_struct p->state =
TASK_UNINTERRUPTIBLE; p->pid = last_pid; p->father = current->pid; p->counter =
p->priority; p->signal = 0; p->alarm = 0; p->leader = 0; /* process leadership
doesn't inherit */ p->utime = p->stime = 0; p->cutime = p->cstime = 0;
p->start_time = jiffies; //设置TSS段,程序运行时CPU中寄存器的值 p->tss.back_link = 0;
p->tss.esp0 = PAGE_SIZE + (long) p; p->tss.ss0 = 0x10; p->tss.eip = eip;
p->tss.eflags = eflags; p->tss.eax = 0; p->tss.ecx = ecx; p->tss.edx = edx;
p->tss.ebx = ebx; p->tss.esp = esp; p->tss.ebp = ebp; p->tss.esi = esi;
p->tss.edi = edi; p->tss.es = es & 0xffff; p->tss.cs = cs & 0xffff; p->tss.ss =
ss & 0xffff; p->tss.ds = ds & 0xffff; p->tss.fs = fs & 0xffff; p->tss.gs = gs &
0xffff; p->tss.ldt = _LDT(nr); p->tss.trace_bitmap = 0x80000000;
//设置当前进程是否使用协处理器 if (last_task_used_math == current) __asm__("clts ; fnsave
%0"::"m" (p->tss.i387)); 对于一个进程我们可以把它看成有三大部分组成

              

task_struct结构体详细介绍:
long state; //进程运行的状态 TASK_RUNNING        0 运行态 TASK_INTERRUPTIBLE    1 可中断状态
TASK_UNINTERRUPTIBLE    2 不可中断状态 TASK_ZOMBIE        3 僵尸状态 TASK_STOPPED      
 4 停止状态  long counter;//进程的执行时间片,表示当前进程能够占用CPU资源的时间 long priority;//进程优先级 long
signal; //信号量位图 32bit每一个bit来表示一个信号 struct sigaction sigaction[32];//信号量 long
blocked; /* bitmap of masked signals */ //信号掩码 /* various fields */ int
exit_code; //退出码 unsigned long start_code,end_code,end_data,brk,start_stack;
//当前进程的内存使用信息 long pid,father,pgrp,session,leader;//father pid unsigned short
uid,euid,suid;//进程的用户ID 进程的有效ID 进程的超级ID unsigned short gid,egid,sgid;//进程的组ID
进程的有效组ID 进程的超级组ID long alarm; //进程的警告标志 long
utime,stime,cutime,cstime,start_time;//有关进程的用户时间 系统时间 当前用户时间 当前系统时间 开始时间
unsigned short used_math;//是否使用协处理器 /* file system info */ int tty; /* -1 if no
tty, so it must be signed *///当前进程是否占用控制台 unsigned short umask; //用户的掩码 struct
m_inode * pwd; //路径 struct m_inode * root; //根目录 struct m_inode *
executable;//执行位图 unsigned long close_on_exec;//执行结束后时候关闭位图 struct file *
filp[NR_OPEN];//当前进程的文件表 FD在这个数组中找到一个file结构体 /* ldt for this task 0 - zero 1 -
cs 2 - ds&ss */ struct desc_struct ldt[3]; //局部描述符表由代码段和数据段组成 /* tss for this
task */ struct tss_struct tss; //程序状态段

技术
©2019-2020 Toolsou All rights reserved,
shiro-oauth 启用第三方认证登录(精华)2020年8月9日 C#基础知识点 反射Java分布式系统高并发解决方案小结415状态码到后台错误keras数据生成器--数据增强 云计算的最大安全风险:安全责任不清Map 判断key对应的value值是否存在-containsKey()关于Navicat for mysql 的2003错误实验11-1-6 指定位置输出字符串 (20 分)golang一行代码将切片转成以分号分隔的字符串