首页
学习
活动
专区
工具
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.4K60

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.8K10

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.5K21

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.1K20
领券