本文共 2702 字,大约阅读时间需要 9 分钟。
进程提供两种虚拟机制,虚拟cpu和虚拟内存linux中所有的进程都在一个list中,可以通过下面的方法来访问集成中的子线程struct task_struct *task;struct list_head *list;list_for_each(list,¤t->children){ task=list_entry(list,struct task_struct,sibling);}这里的sibling是task_struct中的成员变量,表示这个task的所有子进程遍历所有进程struct task_struct *task;for(task=current;task!=&init_task;task=task->parent)获取下一个进程struct task_struct *task;list_entry(task->tasks.next;struct task_struct,tasks)获取前一个进程struct task_struct *task;list_entry(task->tasks.prev;struct task_struct,tasks)通过for_each_process可以遍历所有的taskstruct task_struct *task;for_each_process(task){ printk("%s[%d]",task->comm,task->pid);}user space 通过fork/clone 来创建新的进程,在kernel中通过kthread_create/kthread_run来创建线程,其中kthread_create创建的线程不会立即运行,而kthread_run创建的线程会立即运行.这两者的关系如下:#define kthread_run(threadfn, data, namefmt, ...) \({ \ struct task_struct *__k \ = kthread_create(threadfn, data, namefmt, ## __VA_ARGS__); \ if (!IS_ERR(__k)) \ wake_up_process(__k); \ __k; \})可以在内核线程中调用do_exit()或者kthread_stop()来退出内核线程cfs 调度不在有时间片的概念,而是确保每个进程公平的分配处理器运行时间在kernel/sched_fair.c中的update_curr()函数会更新sched_entity struct sched_entity { /* For load-balancing: */ struct load_weight load; unsigned long runnable_weight; struct rb_node run_node; struct list_head group_node; unsigned int on_rq; u64 exec_start; u64 sum_exec_runtime; u64 vruntime; u64 prev_sum_exec_runtime; u64 nr_migrations; struct sched_statistics statistics;};static void update_curr(struct cfs_rq *cfs_rq){ struct sched_entity *curr = cfs_rq->curr; u64 now = rq_clock_task(rq_of(cfs_rq)); u64 delta_exec; if (unlikely(!curr)) return; #获得单签任务所占用的运行总时间 delta_exec = now - curr->exec_start; if (unlikely((s64)delta_exec <= 0)) return;}调度器的入口是schedule()函数,其要做的事情就会通过pick_next_task()来选择一个高优先级的进程context_switch()来执行进程的切换set_tsk_need_resched()来设置进程中的need_resched标志,clear_tsk_need_resched()来清除need_resched标志,need_resched()用来判断这个标志是否置位用户抢占发生在:从系统调用返回用户空间,从中断处理程序返回用户空间内核抢占发生在:中断程序返回内核空间之前,内核代码再一次具有可抢占性的时候,内核显示调用是schedule(),内核任务阻塞用户空间程序可以条用sched_yield()来放弃cpu遍历链表:list_for_each / list_for_each_entry /list_for_each_entry_reverse遍历的同时删除list_for_each_entry_safe / list_for_each_entry_safe_reverse内核中的队列是通过kfifo来实现的映射是指一个key 关联一个指针存储大量数据,并且要求检索迅速就用红黑树异常与中断不同,它产生是必须考虑与处理器的时钟同步,所以异常也被称为同步中断中断不可以重入,设置IRQF_SHARED标志可以共享中断,用参数dev可以却分是哪个设备的中断软中断执行的是在:硬中断返回时/ksoftirq,显式调用软中断,软中断的入口函数是do_softirq()taskset和软中断 可以工作在中断上下文,而workqueue 只能工作在进程上下文。local_bh_disable/local_bh_enable 可以激活本地处理器的软中断和tasklet的处理内核的同步方法有:原子操作/自旋锁/读写自旋锁/信号量/读写信号量/互斥体/完成量/顺序锁/顺序和屏障vfs中的四个主要对象类型是:超级快对象,索引节点对象,目录项对象,文件对象i/o调度策略:as预测,cfq 完全公正的排队,dealine 最终期限,noop,可以通过命令行仓鼠elevator=as来修改所有块设备的调度策略使用depmod -A 产生模块依赖,模块依赖信息在/lib/modules/version/modules.dep中
转载地址:http://jinmi.baihongyu.com/