标签:linux linux内核 fork 系统调用
首先了解一下程序和进程的概念:
程序:程序是完成特定任务的一系列指令集合。
进程:从用户角度来看,进程是程序的一次执行过程。从系统的角度看,进程是操作系统分配内存和cpu等资源的基本单位,进程是资源分配的最小单位。每一个进程都有自己独立的地址空间与执行状态,像unix这样的多任务操作系统能够让许多程序同时运行,每一个运行着的程序就构成了一个进程。
进程数据结构:
进程的静态描述:由pcb、有关程序段和该程序段所操作的数据结构集。
进程控制块:描述进程情况及控制运行所需要的全部信息
代码段:是进程中能够被进程调度程序在cpu上执行的代码段
数据段:一个进程的数据段,可以是进程对应的程序加工处理的原始数据,也可以是程序执行完毕后产生的中间或者最终数据
进程和程序的区别:
进程是动态的,程序是静态的。
进程的生命周期是相对短暂的,而程序是永久的。
进程数据结构PCB。
一个进程只能对应一个程序,一个程序可以对应多个进程。
进程的状态:就绪、运行、等待(阻塞)
linux内核的进程状态:运行、可中断睡眠、不可中断睡眠、暂停、僵尸等状态,他们的图如下图:
进程调度及其算法:先来先服务算法、时间片轮转法等
0号进程是linux的生命,是内核启动的时候的天字第一号进程。创建完第一个0号进程后,会第一个用户进程就是1号进程, which init/sbin
查看内核进程pid最大配置:cat /proc/sys/kernel/pid_max 32768个
下面来进入主题:
fork系统调用
fork函数的现象就是开启一个新的进程分支,会出现并发情况。
fork函数调用时怎样做到一次调用两次返回的呢?本质上是进程都在各自的内存空间返回,因为每个进程都有自己的内存空间。
子进程拷贝父进程的哪些数据资源呢?代码段、堆栈、数据段、进程控制块(记录了进程的状态,cpu通过进程控制块查询进程的状态)
一个进程是由进程PCB、代码段、数据段、堆栈段。进程是操作系统对资源的一种抽象,PCB是操作系统感知进程存在的一个重要数据结构,言外之意就是会所cpu通过PCB来控制进程。
如果此时在数据段和代码段中有一个文件锁,子进程会拷贝吗?
如果父进程中打开一个文件,那么文件句柄会被子进程拷贝吗?
如果父进程中有一个变量,那么子进程中的变量和父进程中的变量是同一个变量吗?不是,每个进程都有独立的内存空间。
fork函数的返回值是等于0是子进程,大于0是父进程,为什么这样做呢?返回值是子进程的id号,这样父进程可以很方便的控制子进程。一个父进程可以不断的fork子进程,父进程和子进程是一对多的关系,如果创建一个子进程不把子进程的信息返回给父进程,那么父进程就无法控制多个子进程。再者在子进程中获取父进程也是很方便。如果fork进程出错了怎么办?man 2 fork,失败的话返回-1,会创建一个变量errno记录错误信息。
怎么理解子进程的应用代码从fork开始,而不是从声明pid_t变量开始呢?
pid_t pid;
int abc= 6;// 父进程到此处还是改数据段赋值
pid = fork();// 拷贝数据给子进程,没有必要让子进程再赋值
if(pid==-1){
//子进程从此处开始执行
}
下列和helloword会打印几次?8次
int main(){
fork(); // 会产生两个进程分支
fork();// 前面产生的两个进程每个都会产生两个进程,有四个进程
fork();// 前面产生的4个进程都会产生两个进程,总共有八个进程
print("helloworld!");// 八个进程所以会打印八次
return 0;
}
让父进程产生10个进程,请输入要产生多少个进程,每个进程要跑多少圈?
void testFunction(){
print("------------------");
}
int main(){
int procnum = 10;
int loopnum = 100;
int i = 0;
pid_t pid;
for( i=0;i<10;i++){
pid = fork();
if (pid){
for(j =0;j<loopnum ;j++){
testFunciton();
}
exit(0);
}
}
}
本文来源:http://blog.csdn.net/andywuchuanlong
linux: fork系统调用实现剖析
标签:linux linux内核 fork 系统调用
原文地址:http://blog.csdn.net/andywuchuanlong/article/details/45676025