进程管理.docx
《进程管理.docx》由会员分享,可在线阅读,更多相关《进程管理.docx(18页珍藏版)》请在冰豆网上搜索。
进程管理
第3章—进程管理
内核把进程存放在叫做任务队列(tasklist)的双向循环链表中,每一项为进程描述符结构(taskstruct----linux/sched.h)
(taskstruct存在于1所有structtask_struct*next_task,*prev_task连接,支持ps,kill
Linux将task中所有的空槽位用一个链表tarray_freelist连接了起来
3pidhash-structtask_struct*pidhash_next,**pidhash_pprev;
0号进程系统内核swaper1号进程init
Slab分配器分配taskstruct
写时拷贝—代码复制只有在需要写入时才进行,最开始父子共享一个拷贝
实现fork---do_fork()
为进程分配一个task_struct
注意新进程的很多成员要初始化
拷贝文件、信号、进程地址空间等信息
把进程加入运行队列
Fork时创建thread_info,thread_info包含task_struct指针
linux/fs/exec.cdo_execve(char*filename,char**argv,char**envp,structpt_regs*regs)
打开文件,获取文件的file结构
计算exec后的UID/GID,读入文件头
读入命令名,环境变量,起动参数
二进制文件操作函数
内核有个formats的队列,队列上每个元素只识别一种可执行文件,负责进一步处理
ELF格式的处理代码:
load_elf_binary
Vfork—不拷贝叶表项?
线程:
有自己taskstruct,进程操作,只是与其它进程共享某些资源(地址空间)
Windows设定专门处理内核机制,所以平时用进程就好,开销也不是很大
Exit结束进程:
对继承来的资源做释放
do_exit使用exit_notify函数向父进程发送SIGCHLD信号。
接受到SIGCHLD函数的父进程找出成为ZOMBIE状态的子进程,释放其task_struct.
Wait删除进程:
release_task()/free_uid()消除进程拥有者进程使用计数
Unhash_process()从pidhash上删除该进程,从task_list上删
如果被ptrace跟踪
Put_task_struct()释放内核栈和thread_info(thread_info位于内核栈的低地址)所占叶,task_struct所占slab高速缓存
孤儿进程:
给子进程在当前进程组找个进程做父亲,没有就用init----
do_exit()/notify_parent()/forget_original_parent()
函数等待条件时被挂起到对应等待对象的等待队列(硬盘io操作,串口的输入输出),条件满足时被唤醒。
struct_wait_queue注意临界区互斥
struct__wait_queue{unsignedintflags;
#defineWQ_FLAG_EXCLUSIVE0x01
structtask_struct*task;//指向进程
structlist_headtask_list;//此队列指针
#ifWAITQUEUE_DEBUG
long__magic;
long__waker;
#endif};
深度睡眠:
不受中断信号的影响sleep_on:
wake_up:
浅度睡眠:
interruptible_sleep_oninterruptible_wake_up
而在期间操作资源时用到信号灯:
需要等待的类型的资源内定义semaphore型成员,对这个成员进行down函数,up函数操作来完成资源获得和资源解放工作include/asm-i386/semaphore.h
进程组:
会话:
信号:
第4章进程调度
1策略综述:
进程可分为io消耗型和cpu消耗型
调度策略矛盾:
进程响应迅速(响应时间短)最大系统利用率(高吞吐量)
优先级:
高的先响应,占时间片也较长。
用户和系统都可设进程优先级
动态优先级策略:
io消耗型优先级会动态提高,cpu消耗型优先级会动态降低
可根据休眠时间判断是哪种类型
静态优先级Nice(taskstruct->static->prio)-20-+19越低优先级越高.,
Effective_prio()动态优先级根据nice和计算进程交互性函数实现
140位的优先级数组
时间片:
进程被抢占前所能连续运行时间,时间片到不能运行,直到所有进程时间片都没有,
重新分配时间片
有默认值(如20ms),太小频繁切换进程消耗资源,过长系统实时响应差
nr:
就绪进程Wi:
进程i的权重
Linu:
最高优先级(位图第一位置1)的程序总是在运行,分配较大时间片并不一定一次运行完
交互式程序时间片较大,可活动为只在接收时占用cpu,其余时间放弃
抢占cpu:
进入task_running状态进程高于当前正在运行进程优先级,
当一个进程的时间片变为零
2kernel/sched.c
prev当前执行的进程,next将要选出执行的
计算当前进程的时间配额
判断当前进程进入调度后状态
遍历可执行队列比较拿个权值大
判断是否当前进程
切换进程上下文switchto
2.6内核调度改进(p33)
每个处理器都有一个可执行队列,结构runqueue(kernel/sched.c)放在头文件会被共享
{
spinlock_tlock;保护队列运行自旋锁
unsignedlongnr_running;可运行任务数目
unsignedlong cpu_load 基于runqueue平均进程数的CPU加载因子
u64nr_switches;cpu的切换次数
unsignedlongnr_uninterruptible;
structtask_struct*curr,当前运行进程描述符的指针
*idle;指向当前CPU的swappe进程
structmm_struct*prev_mm;在进程却换工程中,保存正被替换的进程的地址空间
//structprio_array*active;活动优先级队列
(最新内核并没有把这两个放进结构体,单独处理)
//structprio_array*expired;过期优先级队列
prio_array_t[2] arrays 激活和expired进程的2维数组
int best_expired_prio 在expired进程中最低的静态优先级
atomic_tnr_iowait 曾经在runqueue但是现在正在等待I/O操作完成的进程数
structsched_domain* sd 指向当前CPU的基本调度域
int active_balance 标志一些进程将被从一个requeue转移到其他requeue队列
int push_cpu 没有使用
structtask_struct*migration_thread;内核转移线程的进程描述符
structlist_headmigration_queue;将被从requeue中转移的进程列表
}
获得执行队列1当前处理器this_rq()
2特定处理器cpu_rq(processor)
3给定任务队列task_rq(task)
对可执行队列操作前上锁rq=task_rq_lock(task,flags)task_rq_unlock(rq,flags)
或this_rq_lock()/rq_unlock()
自旋锁:
防止多个任务对可执行队列同时进行操作,其它任务循环查询锁是否解锁
多个队列的获得锁,必须按一定顺序(地址高低)---防止死锁
优先级数组:
structprio_array(kernel/sched.c)两个队列一个过期一个未过期
Intnr_active任务数目,
Unsignedlongbitmap[5];优先级位图,进入就绪对应位置1。
查找sched_find_first_bit()
Structlist_headqueue[140];优先级队列,每个优先级一个(prev,next),包含所有同优先级可执行,对于同优先级调度,轮循
重新计算时间片:
时间片到的进程被移至过期队列,连到过期队列时,已计算好新的时间片
当所有运行队列中进程数(nr_active)减为0,把过期队列指针赋给运行队列
Schedule()fifo先进先出实时性强/rr基于优先级轮循适合运行时间较长进程/other
调度显然要维护执行队列的指针(structtask_structcurrent)
执行->睡眠就绪->执行执行->暂停
处理调度任务队列
是否在中断处理中
底半处理
调整运行进程队列,新进程入队插入在队头,SCHED_RR当前进程移到运行进程队列的最后
选择下一个要运行的进程,weight值最大的进程作为下一个要运行的进程
切换
structtask_struct{
/*
*offsetsofthesearehardcodedelsewhere-touchwithcare
*/
volatilelongstate;/*-1unrunnable,0runnable,>0stopped*/
//set_task_state(task,state)或直接赋值
//TASK_RUNNING
//TASK_INTERRUPTIBLE阻塞睡眠条件到或接收信号醒
//TASK_ZOMBIE僵死exit()退出,要wait()清理
//TASK_STOPPED
unsignedlongflags;/*perprocessflags,definedbelow*/
intsigpending;
mm_segment_taddr_limit;/*threadaddressspace:
0-0xBFFFFFFFforuser-thead
0-0xFFFFFFFFforkernel-thread
*/
structexec_domain*exec_domain;
volatilelongneed_resched;//调度信息:
是否需要重新调度
unsignedlongptrace;
intlock_depth;/*Lockdepth*/
/*
*offset32beginshereon32-bitplatforms.Wekeep
*allfieldsinasinglecachelinethatareneededfor
*thegoodness()loopinschedule().
*/
longcounter;//调度信息:
进程可以运行的剩余时间
longnice;
unsignedlongpolicy;//进程使用的调度策略
intprocessor;
/*
*cpus_runnableis~0iftheprocessisnotrunningonany
*CPU.It's(1<*isupdatedundertherunqueuelock.
*
*TodeterminewhetheraprocessmightrunonaCPU,this
*maskisAND-edwithcpus_allowed.
*/
unsignedlongcpus_runnable,cpus_allowed;
/*
*(onlythe'next'pointerfitsintothecacheline,but
*that'sjustfine.)
*/
structlist_headrun_list;
unsignedlongsleep_time;
structtask_struct*next_task,*prev_task;//所有
structmm_struct*mm;//内存的叶段,栈。
task_struct->mm_struct->页表->内存
structmm_struct*active_mm;//mm_struct结构描述了进程的虚拟内存信息
structlist_headlocal_pages;
unsignedintallocation_order,nr_local_pages;
/*taskstate*/
structlinux_binfmt*binfmt;
intexit_code,exit_signal;
intpdeath_signal;/*Thesignalsentwhentheparentdies*/
/*?
?
?
*/
unsignedlongpersonality;
intdid_exec:
1;
pid_tpid;进程标示符。
进程唯一标示。
最大32768
pid_tpgrp;
pid_ttty_old_pgrp;
pid_tsession;
pid_ttgid;
/*booleanvalueforsessiongroupleader*/
intleader;
/*
*pointersto(original)parentprocess,youngestchild,youngersibling,
*oldersibling,respectively.(p->fathercanbereplacedwith
*p->p_pptr->pid)
*/
structtask_struct*p_opptr,*p_pptr,*p_cptr,*p_ysptr,*p_osptr;
//父指针,孩子,兄弟
structlist_headthread_group;
/*PIDhashtablelinkage.*/
structtask_struct*pidhash_next;
structtask_struct**pidhash_pprev;
wait_queue_head_twait_chldexit;/*forwait4()*/
structcompletion*vfork_done;/*forvfork()*/
//////////priority
unsignedlongrt_priority;//实时进程的静态优先级
unsignedlongit_real_value,it_prof_value,it_virt_value;
unsignedlongit_real_incr,it_prof_incr,it_virt_incr;
structtimer_listreal_timer;
structtmstimes;
unsignedlongstart_time;
longper_cpu_utime[NR_CPUS],per_cpu_stime[NR_CPUS];
/*mmfaultandswapinfo:
thiscanarguablybeseenaseithermm-specificorthread-specific*/
unsignedlongmin_flt,maj_flt,nswap,cmin_flt,cmaj_flt,cnswap;
intswappable:
1;
/*processcredentials*/
uid_tuid,euid,suid,fsuid;//进程描述符
gid_tgid,egid,sgid,fsgid;
intngroups;
gid_tgroups[NGROUPS];
kernel_cap_tcap_effective,cap_inheritable,cap_permitted;
intkeep_capabilities:
1;
structuser_struct*user;//用户信息,包括用户拥有的进程数目,打开的文件数目
在do_fork时atmoic宏定义组,查看上限
/*limits*/
structrlimitrlim[RLIM_NLIMITS];//用于资源管理,受控资源上限10项linux/include/linux/resouurs.h
unsignedshortused_math;
charcomm[16];
/*filesysteminfo*/
intlink_count,total_link_count;
structtty_struct*tty;/*NULLifnotty*/
unsignedintlocks;/*Howmanyfilelocksarebeingheld*/
/*ipcstuff*/
structsem_undo*semundo;
structsem_queue*semsleeping;
/*CPU-specificstateofthistask*/
structthread_structthread;
/*filesysteminformation*/
structfs_struct*fs;//文件系统的信息
/*openfileinformation*/
structfiles_struct*files;//指向每一个打开的文件描述符
/*signalhandlers*/属于通信机制
spinlock_tsigmask_lock;/*Protectssignalandblocked*/
structsignal_struct*sig;
sigset_tblocked;
structsigpendingpending;
unsignedlongsas_ss_sp;
size_tsas_ss_size;
int(*notifier)(void*priv);
void*notifier_data;
sigset_t*notifier_mask;
/*Threadgrouptracking*/
u32parent_exec_id;
u32self_exec_id;
/*Protectionof(de-)allocation:
mm,files,fs,tty*/
spinlock_talloc_lock;
/*journallingfilesysteminfo*/
void*journal_info;
};
与进程相关
structfs_struct{
atomic_tcount;
rwlock_tlock;
intumask;
structdentry*root,*pwd,*altroot;//进程的根目录,可利用chdir改变
查找从当前目录pwd开始,要从根开始多麻烦task_struct有这个结构的指针
structvfsmount*rootmnt,*pwdmnt,*altrootmnt;文件系统的信息
};
structmm_struct{
structvm_area_struct*mmap;/*listofVMAs*/内核区域链表,所有mm_struct连在同一个链表中,访问时上锁,内存描述符的总数放在
structrb_rootmm_rb;虚拟内存区域红黑树
structvm_area_struct*mmap_cache;/*lastfind_vmaresult*/最后使用的内存区域
unsignedlong(*get_unmapped_area)(structfile*filp,
unsignedlongaddr,unsignedlonglen,
unsignedlongpgoff,unsignedlongflags);
void(*unmap_area)(structmm_struct*mm,unsignedlongaddr);
unsignedlongmmap_base;/*baseofmmaparea*/
unsignedlongtask_size;/*sizeoftaskvmspace*/
unsignedlongcached_hole_size;/*ifnon-zero,thelargestholebelowfree_area_cache*/
unsignedlongfree_area_cache;/*firstholeofsizecached_hole_sizeorlarger*/
pgd_t*pgd;叶全局目录—装换并将值存入cr3作为页表基地址
atomic_tmm_users;/*Howmanyuserswithuserspace?
*/
当前使用该内存的进程计数,可被多个进程使用
atomic_tmm_count;/*Howmanyreferencesto"structmm_struct"(userscountas1)*/
intmap_count;/*numberofVMAs*/
structrw_semaphoremmap_sem;访问互斥信号量
spinlock_tpage_table_lock;/*Protectspagetablesandsomecounters*/
structlist_headmmlist;/*Listofmaybeswappedmm's.Thesearegloballystrung
*togetheroffinit_