国内网站建设公司排名,wordpress 301,app制作开发报价,怎么查看网站虚拟空间转载#xff1a;https://blog.csdn.net/qq_28840229/article/details/79844763
fork之后#xff1a;
父子相同处: 全局变量、.data、.text、栈、堆、环境变量、用户ID、宿主目录、进程工作目录、信号处理方式...
父子不同处: 1.进程ID 2.fork返回值 3.父进程ID 4.进…转载https://blog.csdn.net/qq_28840229/article/details/79844763
fork之后
父子相同处: 全局变量、.data、.text、栈、堆、环境变量、用户ID、宿主目录、进程工作目录、信号处理方式...
父子不同处: 1.进程ID 2.fork返回值 3.父进程ID 4.进程运行时间 5.闹钟(定时器) 6.未决信号集
似乎子进程复制了父进程0-3G用户空间内容以及父进程的PCB但pid不同。真的每fork一个子进程都要将父进程的0-3G地址空间完全拷贝一份然后在映射至物理内存吗
当然不是!父子进程间遵循读时共享写时复制的原则。这样设计无论子进程执行父进程的逻辑还是执行自己的逻辑都能节省内存开销。
1、fork函数时调用一次返回两次。在父进程和子进程中各调用一次。子进程中返回值为0父进程中返回值为子进程的PID。程序员可以根据返回值的不同让父进程和子进程执行不同的代码。子进程是父进程的副本获得了父进程数据空间、堆和栈的副本父子进程并不共享这些存储空间共享正文段即代码段因此子进程对变量的所做的改变并不会影响父进程。一般来说fork之后父、子进程执行顺序是不确定的这取决于内核调度算法。进程之间实现同步需要进行进程通信。
子进程对数据进行减一操作父进程做加一操作
#include stdio.h #include unistd.h #include stdlib.h int main() { pid_t pid; char *message; int n 0; pid fork(); while(1){ if(pid 0){ perror(fork failed\n); exit(1); } else if(pid 0){ n--; printf(childs n is:%d\n,n); } else{ n; printf(parents n is:%d\n,n); } sleep(1); } exit(0); } 2、进程等待
孤儿进程 父进程生成子进程但是父进程比子进程先结束子进程会变成孤儿进程由系统1号init 进程进行接管。init 进程接管后在该孤儿进程结束的时候负责“收尸”回收系统资源及进程信息。
僵尸进程子进程已经退出但是没有父进程回收它的资源父进程生成的子进程但是子进程比父进程先挂掉如果父进程没有收回它的资源时那么子进程挂掉后就变成了僵尸进程应该尽量避免产生僵尸进程可以在父进程调用wait 或者waitpid 进程回收。
进程一旦调用了wait就立即阻塞自己由wait 自动分析是否当前进程的某个子进程已经退出。如果让它找到了这样一个已经变成僵尸的子进程wait 就会收集这个子进程的信息并把它彻底销毁后返回如果没有找到这样一个子进程wait 就会一直阻塞在这里直到有一个出现为止。
补充 进程0
内核是一个大的程序可以控制硬件也可以创建、运行、终止、控制所有的进程。当内核被加载到内存后首先就会有完成内核初始化的函数start_kernel()从无到有的创建一个内核线程swap并设置其PID为0即进程0它也叫闲逛进程进程0执行的是cpu_idle()函数该函数仅有一条hlt汇编指令就是在系统闲置时用来降低电力的使用和减少热的产生。同时进程0的PCB叫做init_task在很多链表中起了表头的作用。
当就绪队列中再没有其他进程时闲逛进程就会被调度程序选中以此来省电减少热量的产生。
进程1
即init进程。首先内核线程kernel_init执行内核的一些初始化函数以将内核初始化。那么此内核态的线程又是怎样变为一个用户进程的实际上kernel_int()内核函数中调用了execve()系统调用该系统调用装入用户态下的一个可执行程序init从而启动用户进程init进程。注意内核函数kernel_init()与用户态下的可执行文件init是不同的位置不同运行状态不同代码也不同。init进程只是内核线程kernel_init启动起来的一个普通的用户进程当然也是用户态下的第一个进程并且init进程从不终止用来创建和监控操作系统外层的所有进程的活动。 3、父进程创建多个子进程问题
void createsubprocess(int num) { pid_t pid; int i; for(i0;inum;i) { pidfork(); if(pid0||pid-1) //子进程或创建进程失败均退出,这里是关键所在子进程中跳出循环。 { break; } } if(pid-1) { perror(fail to fork!\n); exit(1); } else if(pid0) { printf(子进程id%d,其对应的父进程id%d\n,getpid(),getppid()); exit(0); } else { printf(父进程id%d\n,getpid()); exit(0); } }