首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

通过linux0.11理解僵尸进程

首先僵尸进程产生的原因是子进程退出了,但是父进程没有回收他的资源(pcb),所以我们从源头开始分析这个过程。那就是子进程退出的时候。进程是通过exit系统调用退出的。 我们看一下exit函数的代码。...1 修改当前进程的子进程的新父进程为init进程。如果子进程已经退出了,则通知init进程。否则init无法回收该子进程的资源。 2 释放一系列资源。 3 修改进程状态和退出码。...4 给父进程发SIGCHLD信号。 5 重新调度。因为自己退出了。 我们可以知道,一个进程调用exit的时候,他就已经成为僵尸进程了。这时候如果父进程不处理这个事情,则退出的子进程会一直占据pcb。...// 子进程的新父进程进程id为1的进程 task[i]->father = 1; /* 父进程没有调wait,子进程退出了,然后父进程也退出了...如果这时候当前进程的某些进程已经退出了(当前进程没有调waitpid处理子进程的退出),则给init进程发送SIGCHLD信号。这时候init会回收这个子进程的pcb。下面是init进程的逻辑。

2K20

linux0.11进程调度源码分析

下面是进程调度函数及其相关函数的代码。...task_struct ** p; /* check alarm, wake up any interruptible tasks that have got a signal */ // 处理进程的信号和状态...,相与 得到进程当前阻塞的集合,即排除进程阻塞了不能阻塞的信号,然后取反得到可以接收的 信号集合,再和signal相与,得到当前进程当前收到的信号...switch_to(next); } #define switch_to(n) {\ struct {long a,b;} __tmp; \ // ecx是第n个进程对应的pcb首地址,判断切换的下一个进程是不是就是当前执行的进程...如果时间用完则直接重新调度,否则进程可以继续执行。进程调度的时候,系统会选择时间最长的进程,防止有的进程得不到执行,当所有进程的时间片都消耗完毕,则重新计算时间。

1.7K20
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    linux0.11进程睡眠唤醒原理分析

    进程的睡眠是通过调用sleep_on函数,该函数修改了进程的状态并且通过schedule函数切换到其他进程执行,从而实现进程的挂起,TASK_UNINTERRUPTIBLE状态的进程只能被wake_up...TASK_INTERRUPTIBLE状态的进程可以被wake_up和信号唤醒。唤醒的时候也是通过修改进程的状态为可运行,然后等待下一次进程调度,被唤醒的进程不一定马上得到执行。...} // 当前进程挂载到睡眠队列p中,p指向队列头指针的地址 void sleep_on(struct task_struct **p) { struct task_struct *tmp;...,这个版本的实现没有采用真正链表的形式, 他通过每个进程在栈中的临时变量形成一个链表,每个睡眠的进程, 在栈里有一个变量指向后面一个睡眠节点,然后把链表的头指针指向当前进程...自己被信号唤醒了, 去唤醒别的进程,自己却还睡眠 */ if (*p && *p !

    2.3K40

    Linux 考古笔记

    2 流程分析 2.1 引导内核阶段 2.2 内核启动阶段 2.3 init 进程启动 2.4 shell 命令执行 Linux0.11 考古笔记 最近读完《Linux 内核完全注释》和《品读 Linux0.11...核心代码》,大致理解下 Linux0.11 内核的全貌。...1.4 如何理解进程控制? 程序是一个可执行的文件,而进程是一个执行中的程序实例。关于 Linux0.11 操作系统的进程设计,这里仅侧重理解几个比较重要的概念。...2 流程分析 根据《品读 Linux0.11 核心代码》这个专栏,它是按照系统启动到运行的时间顺序结合 Linux0.11 源码来展开的,我根据专栏的内容进行二次整理。...其中将 bootsect.s 搬到 0x9000 地址, setup.s 程序( 2~5 扇区)加载到 0x90200 地址,将 system 模块( 240 个扇区)加载到 0x10000 地址。

    1.1K30

    通过linux0.11源码理解进程的虚拟地址、线性地址、物理地址

    进程的地址有三种,分别是虚拟地址(逻辑地址)、线性地址、物理地址。在分析之前先讲一下进程执行的时候,地址的解析过程。...在这里插入图片描述 下面选择子的计算 /* * Entry into gdt where to find first TSS. 0-nul, 1-cs, 2-ds, 3-syscall * 4-TSS0, 5-...n是0,tss是32 #define _TSS(n) ((((unsigned long) n)<<4)+(FIRST_TSS_ENTRY<<3)) // 第一个ldt选择子的偏移是5<<3,5乘以8,...#define PAGE_ALIGN(n) (((n)+0xfff)&0xfffff000) /* 段描述符的地3,4,5,7四个字节是保存基地址 把edx的两个字节保存在addr+2,...最后根据tss中的cs和ip执行进程。这就是文章开头的过程。这就是linux0.11版本中进程地址管理的实现。下面是fork后的结构图。 ?

    1.5K60

    linux缺页中断源码分析(基于linux0.11

    12) & 0x3ff] = page | 7; /* no need for invalidate */ // 返回线性地址 return page; } 2 否则先判断是否有另一个进程和当前进程使用了同一个执行文件...current->executable) return 0; // 只有当前进程使用这个可执行文件则返回 if (current->executable->i_count...= current->executable) continue; // 找到一个不是当前进程,但都执行了同一个可执行文件的进程 if (try_to_share...= current, and that they * share the same executable. */ // 使得另一个进程的页目录和页表项指向另一个进程的正在使用的物理地址 static...(线性地址),取得p进程的页目录项地址,再加上address算出的偏移 from_page += ((p->start_code>>20) & 0xffc); // 取得当前进程的页目录项地址

    1.9K10

    nginx源码阅读(5)Master进程浅析

    (SIG_SETMASK,&prevMask,NULL); //4-解除阻塞 pause(); //5-等待信号 sigprocmask(SIG_BLOCK,&initMask,&prevMask...假设某一个信号,在上面的4之后,5之前到来,也就是解除阻塞之后,等待信号调用之前到来,信号会被信号处理器所处理,并且pause调用会一直陷入阻塞,除非有第二个信号的到来。这和我们的预期是不符的。...这种方式,不如共享内存使用的广泛,目前主要被使用在master进程广播消息到子进程,这里面的消息包括下面5种: #define NGX_CMD_OPEN_CHANNEL 1 //新建或者发布一个通信管道...子进程向master通信也是如此。这样在fork N个子进程之后,实际上会建立N个socket channel,如图5所示。...图5-master和子进程通过socket channel通信原理 在nginx中,对于socket channel的使用,总是使用channel[0]作为数据的发送端,channel[1]作为数据的接收端

    1.7K21

    由浅入深的了解进程(5)--环境变量

    所以根据上一章写过的在运行程序之前会有bash的命令执行的话,说明环境变量默认也是可以被子进程拿到的。环境变量默认存在的就是在bash内部(不过我们还没说能够被子进程修改从父进程那得到的数据)。...所以现在bash进程启动的时候,默认会生成两个表,argv[]命令行参数表,env[]环境变量表,bash通过各种方式交予进程。...环境变量本身具有系统级别的全局属性,因为环境变量本身能够被子进程继承下去。...那子进程的数据这么能够给到bash父进程呢? 因为export,echo的一些命令,这些命令叫做内建命令(80%的命令都是bash创建子进程进行的,但是剩下的一些就是由bash亲自进行的)。...我们上一篇文章中介绍的echo不是bash的子进程而是内建命令,就能够很好的说明,echo能够直接读到本地变量。因为是不能够继承给子进程,说明内建命令就不是子进程,而是bash直接进行的。

    5510

    linux0.11系统调用过程和fork源码解析

    pcb地址赋值给eax movl _current,%eax // 判断当前进程状态,0是可执行,即判断当前进程是否可以继续执行 cmpl $0,state(%eax)....align 2 _sys_fork: // 执行find_empty_process函数,返回一个进程id在eax里 call _find_empty_process // 看是否找到可用的进程...tss信息中的ldt索引首先从gdt找到进程ldt 结构体数据的首地址,然后根据当前段的属性,比如代码段, 则从cs中取得选择子,系统从ldt表中取得进程线性空间 的首地址、限长...主要是判断是否需要重新调度进程。接下来进行信号的处理。信号另外分析,这里假设没有信号,则直接跳转到标签3。...父进程返回值是eax,即子进程id。子进程的eax是0所以是返回值是0。

    1.4K40

    Android系统启动——5 zyogte进程(Java篇)

    本篇文章的主要内容如下: 1、Java层的ZygoteInit的main()方法 2、registerZygoteSocket(socketName)方法解析 3、预加载系统类和资源 4、启动SystemServer 5、...ex); closeServerSocket(); throw ex; } } 我将ZygoteInit的main()方法分为5个阶段...signal信号处理函数 第2步:fork子进程 第3步:在子进程挂载external storage 第4步:在子进程设置用户Id、组Id和进程所属的组 第5步:在在进程执行系统调用setrlimit...我将这个函数内部分为5部分,如下: 1、关闭Zygote的socket两端的连接 2、通过设置umask创建文件的默认权限 3、设置进程名字 4、获取SYSTEMSERVERCLASSPATH环境变量值...3.5、 第5部分 上面结束后,如果返回的pid等于0,表示处于子进程中,执行handleChildProc(),如果pid不等于0,则表示在zygote进程中,则调用handleParentProc(

    2.3K20
    领券