Linux 源码阅读 进程管理
Linux 源码阅读 进程管理
版本:2.6.24
1.准备知识
1.1 Linux系统中,进程是最小的调度单位;
1.2 PCB数据结构:task_struct (Location:linux-2.6.24\include\linux\sched.h)(任务可以和进程混用)
2.设计思路图
3.数据结构
4.主要函数
4.1创建进程
long do_fork(unsigned long clone_flags,
unsigned long stack_start,
struct pt_regs *regs,
unsigned long stack_size,
int __user *parent_tidptr,
int __user *child_tidptr)
{
struct task_struct *p;
int trace = ;
long nr; if (unlikely(current->ptrace)) {
trace = fork_traceflag (clone_flags);
if (trace)
clone_flags |= CLONE_PTRACE;
} p = copy_process(clone_flags, stack_start, regs, stack_size,
child_tidptr, NULL);
/*
* Do this prior waking up the new thread - the thread pointer
* might get invalid after that point, if the thread exits quickly.
*/
if (!IS_ERR(p)) {
struct completion vfork; /*
* this is enough to call pid_nr_ns here, but this if
* improves optimisation of regular fork()
*/
nr = (clone_flags & CLONE_NEWPID) ?
task_pid_nr_ns(p, current->nsproxy->pid_ns) :
task_pid_vnr(p); if (clone_flags & CLONE_PARENT_SETTID)
put_user(nr, parent_tidptr); if (clone_flags & CLONE_VFORK) {
p->vfork_done = &vfork;
init_completion(&vfork);
} if ((p->ptrace & PT_PTRACED) || (clone_flags & CLONE_STOPPED)) {
/*
* We'll start up with an immediate SIGSTOP.
*/
sigaddset(&p->pending.signal, SIGSTOP);
set_tsk_thread_flag(p, TIF_SIGPENDING);
} if (!(clone_flags & CLONE_STOPPED))
wake_up_new_task(p, clone_flags);
else
p->state = TASK_STOPPED; if (unlikely (trace)) {
current->ptrace_message = nr;
ptrace_notify ((trace << ) | SIGTRAP);
} if (clone_flags & CLONE_VFORK) {
freezer_do_not_count();
wait_for_completion(&vfork);
freezer_count();
if (unlikely (current->ptrace & PT_TRACE_VFORK_DONE)) {
current->ptrace_message = nr;
ptrace_notify ((PTRACE_EVENT_VFORK_DONE << ) | SIGTRAP);
}
}
} else {
nr = PTR_ERR(p);
}
return nr;
}
do_fork()函数(Locatiion:linux-2.6.24\kernel\fork.c)
asmlinkage int sys_vfork(struct pt_regs regs)
{
return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs.esp, ®s, , NULL, NULL);
}
vfork()函数(location:linux-2.6.24\arch\x86\kernel\process_32.c)
asmlinkage int sys_fork(struct pt_regs regs)
{
return do_fork(SIGCHLD, regs.esp, ®s, , NULL, NULL);
}
fork()函数(location:linux-2.6.24\arch\x86\kernel\process_32.c)
asmlinkage int sys_clone(struct pt_regs regs)
{
unsigned long clone_flags;
unsigned long newsp;
int __user *parent_tidptr, *child_tidptr; clone_flags = regs.ebx;
newsp = regs.ecx;
parent_tidptr = (int __user *)regs.edx;
child_tidptr = (int __user *)regs.edi;
if (!newsp)
newsp = regs.esp;
return do_fork(clone_flags, newsp, ®s, , parent_tidptr, child_tidptr);
}
clone()函数(location:linux-2.6.24\arch\x86\kernel\process_32.c)
/*
* schedule() is the main scheduler function.
*/
asmlinkage void __sched schedule(void)
{
struct task_struct *prev, *next;
long *switch_count;
struct rq *rq;
int cpu; need_resched:
preempt_disable();
cpu = smp_processor_id();
rq = cpu_rq(cpu);
rcu_qsctr_inc(cpu);
prev = rq->curr;
switch_count = &prev->nivcsw; release_kernel_lock(prev);
need_resched_nonpreemptible: schedule_debug(prev); /*
* Do the rq-clock update outside the rq lock:
*/
local_irq_disable();
__update_rq_clock(rq);
spin_lock(&rq->lock);
clear_tsk_need_resched(prev); if (prev->state && !(preempt_count() & PREEMPT_ACTIVE)) {
if (unlikely((prev->state & TASK_INTERRUPTIBLE) &&
unlikely(signal_pending(prev)))) {
prev->state = TASK_RUNNING;
} else {
deactivate_task(rq, prev, );
}
switch_count = &prev->nvcsw;
} if (unlikely(!rq->nr_running))
idle_balance(cpu, rq); prev->sched_class->put_prev_task(rq, prev);
next = pick_next_task(rq, prev); sched_info_switch(prev, next); if (likely(prev != next)) {
rq->nr_switches++;
rq->curr = next;
++*switch_count; context_switch(rq, prev, next); /* unlocks the rq */
} else
spin_unlock_irq(&rq->lock); if (unlikely(reacquire_kernel_lock(current) < )) {
cpu = smp_processor_id();
rq = cpu_rq(cpu);
goto need_resched_nonpreemptible;
}
preempt_enable_no_resched();
if (unlikely(test_thread_flag(TIF_NEED_RESCHED)))
goto need_resched;
}
schdule()函数(Location:linux-2.6.24\kernel\sched.c
4.2进程调度
Linux 源码阅读 进程管理的更多相关文章
- linux源码阅读笔记 数组定义
在阅读linux源码的过程中遇到了下面的略显奇怪的结构体数组定义. static struct hd_struct{ long start_sect; long nr_sects; }hd[10]={ ...
- linux源码阅读笔记 asm函数
在linux源码中经常遇到__asm__函数.它其实是函数asm的宏定义 #define __asm__ asm,asm函数让系统执行汇编语句. __asm__常常与__volatile__一起出现. ...
- linux源码阅读笔记 fork函数
在阅读源码的过程中,发现找不到fork函数的定义.后来在linux/init/main.c中找到了这样一条语句 static inline _syscall0(int,fork) 原来这里就是fork ...
- Nutch源码阅读进程1---inject
最近在Ubuntu下配置好了nutch和solr的环境,也用nutch爬取了一些网页,通过solr界面呈现,也过了一把自己建立小搜索引擎的瘾,现在该静下心来好好看看nutch的源码了,先从Inject ...
- Nutch源码阅读进程5---updatedb
看nutch的源码仿佛就是一场谍战片,而构成这精彩绝伦的谍战剧情的就是nutch的每一个从inject->generate->fetch->parse->update的环节,首 ...
- Nutch源码阅读进程3---fetch
走了一遍Inject和Generate,基本了解了nutch在执行爬取前的一些前期预热工作,包括url的过滤.规则化.分值计算以及其与mapreduce的联系紧密性等,自我感觉nutch的整个流程是很 ...
- Nutch源码阅读进程2---Generate
继之前仓促走完nutch的第一个流程Inject后,再次起航,Debug模式走起,进入第二个预热阶段Generate~~~ 上期回顾:Inject主要是将爬取列表中的url转换为指定格式<T ...
- Nutch源码阅读进程3
走了一遍Inject和Generate,基本了解了nutch在执行爬取前的一些前期预热工作,包括url的过滤.规则化.分值计算以及其与mapreduce的联系紧密性等,自我感觉nutch的整个流程是很 ...
- Nutch源码阅读进程5
看nutch的源码仿佛就是一场谍战片,而构成这精彩绝伦的谍战剧情的就是nutch的每一个从inject->generate->fetch->parse->update的环节,首 ...
随机推荐
- mysql 开发基础系列1 表查询操作
在安装完数据库后,不管是windows 还是linux平台, mysql的sql命令都大同小异,相关命令都是相同的,每个命令结束后 都以 ; 结尾, 注意在windows平台中表名是不区分大小写 ...
- 从面试连跪到收割offer,回顾我的春招面试历程(研发岗位)
本文首发于自微信公众号[程序员江湖] 作者How 2 Play Life,985 软件硕士,阿里 Java 研发工程师,在技术校园招聘.自学编程.计算机考研等方面有丰富经验和独到见解,目前致力于分享程 ...
- Perl:写POD文档
官方手册:https://perldoc.perl.org/perlpod.html POD文档是perl的man文档,可以用perldoc输出,也可以直接用man输出.在开始下面的文章之前,请先粗略 ...
- vue_drf之实现极验滑动验证码
一.需求 1,场景 我们在很多登录和注册场景里,为了避免某些恶意攻击程序,我们会添加一些验证码,也就是行为验证,让我们相信现在是一个人在交互,而不是一段爬虫程序.现在市面上用的比较多的,比较流行的是极 ...
- YARN集群的mapreduce测试(三)
将user表.group表.order表关:(类似于多表关联查询) 测试准备: 首先同步时间,然后 开启hdfs集群,开启yarn集群:在本地"/home/hadoop/test/" ...
- EF(EntityFramework)与mysql使用,序列化问题[System.ObjectDisposedException]
在EF 中使用mysql关联取数据时,如果当前实体中包含另一个实体的list成员,而这个成员为空的话,在json序列化的时候就会报错: '((System.Data.Entity.DynamicPro ...
- c# 静态构造函数与构造函数的调用先后
先上代码: 测试类: /// <summary> /// 构造函数 /// </summary> public RedisHelper() { Console.WriteLin ...
- Windows server 2008 R2端口转发
查询配置了转发的端口 netsh interface portproxy show v4tov4 配置转发(所有ip访问192.168.0.99的1001端口均指向1953端口) netsh inte ...
- 如何理解php的依赖注入
之前写过关于php依赖注入的文章..最近发现有的朋友对这个还是理解模糊,在这里我想写个简单的实例帮助朋友们理解下...传统的思路是应用程序用到一个A类,就会创建A类并调用A类的方法,假如这个方法内需要 ...
- spring_05装配bean
一.前言 <bean id="user1" scope="singleton" init-method="myInit" destro ...