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

时间: 2024-10-10 10:18:56

linux: fork系统调用实现剖析的相关文章

《Linux内核分析》 week6作业-Linux内核fork()系统调用的创建过程

一.进程控制块PCB-stack_struct 进程在操作系统中都有一个结构,用于表示这个进程.这就是进程控制块(PCB),在Linux中具体实现是task_struct数据结构,它主要记录了以下信息: 状态信息,例如可执行状态.就绪状态.阻塞状态等. 性质,由于unix有很多变种,进行有自己独特的性质. 资源,资源的链接比如内存,还有资源的限制和权限等. 组织,例如按照家族关系建立起来的树(父进程.子进程等). task_struct结构体内容非常庞大,暂时没有去分析源代码,以后有时间再去研究

linux中fork()系统调用总结

由fork创建的新进程被称为子进程(child process).该函数被调用一次,但返回两次.两次返回的区别是子进程的返回值是0,而父进程的返回值则是新进程(子进程)的进程 id.将子进程id返回给父进程的理由是:因为一个进程的子进程可以多于一个,没有一个函数使一个进程可以获得其所有子进程的进程id.对子进程来说,之所以fork返回0给它,是因为它随时可以调用getpid()来获取自己的pid:也可以调用getppid()来获取父进程的id.(进程id 0总是由交换进程使用,所以一个子进程的进

linux内核系统调用和标准C库函数的关系分析

今天研究了一下系统调用和标准库函数的区别和联系,从网上搜集的资料如下: 1.系统调用是为了方便应用使用操作系统的接口,而库函数是为了方便人们编写应用程序而引出的,比如你自己编写一个函数其实也可以说就是一个库函数. 2.系统调用可以理解为内核提供给我们在用户态用的接口函数,可以认为是某种内核的库函数. 3.read就是系统调用,而fread就是C标准库函数. 4.很多c函数库中的函数名与系统调用的名称一样是因为该函数本身其实就是调用的系统调用,放到c函数库就是为了用户态的使用 5.写程序直接使用的

深入解析Linux内核I/O剖析(open,write实现)

Linux内核将一切视为文件,那么Linux的文件是什么呢?其既可以是事实上的真正的物理文件,也可以是设备.管道,甚至还可以是一块内存.狭义的文件是指文件系统中的物理文件,而广义的文件则可以是Linux管理的所有对象.这些广义的文件利用VFS机制,以文件系统的形式挂载在Linux内核中,对外提供一致的文件操作接口. 从数值上看,文件描述符是一个非负整数,其本质就是一个句柄,所以也可以认为文件描述符就是一个文件句柄.那么何为句柄呢?一切对于用户透明的返回值,即可视为句柄.用户空间利用文件描述符与内

read系统调用深度剖析

本文转自:http://blog.csdn.net/unbutun/article/details/6101354#ibm-pcon Read 系统调用在用户空间中的处理过程 Linux 系统调用(SCI,system call interface)的实现机制实际上是一个多路汇聚以及分解的过程,该汇聚点就是 0x80 中断这个入口点(X86 系统结构).也就是说,所有系统调用都从用户空间中汇聚到 0x80 中断点,同时保存具体的系统调用号.当 0x80 中断处理程序运行时,将根据系统调用号对不同

linux下系统调用、API、系统命令,内核函数的区别与联系

1.系统调用: 应用程序和内核间的桥梁,是应用程序访问内核的入口点;但通常情况下,应用程序通过操作系统提供的API进行编程而不是使用系统调用直接编程; linux的全部系统调用加起来大约只有250个左右. 2.API: API常以c库(libc)的形式提供,c库提供了绝大部分API,每个系统调用在c库中都有对应的封装函数(通常封装函数与系统调用的名称相同).系统调用与c库函数并不是一一对应的,有些c库函数可能使用多个系统调用来实现,也有可能多个c库函数使用同一个系统调用来实现,也有些c库函数不使

fork系统调用(转载)

(1) fork系统调用说明 fork系统调用用于从已存在进程中创建一个新进程,新进程称为子进程,而原进程称为父进程.fork调用一次,返回两次,这两个返回分别带回它们各自的返回值,其中在父进程中的返回值是子进程的进程号,而子进程中的返回值则返回 0.因此,可以通过返回值来判定该进程是父进程还是子进程. 使用fork函数得到的子进程是父进程的一个复制品,它从父进程处继承了整个进程的地址空间,包括进程上下文.进程堆栈.内存信息.打开的文件描述符.信号控制设定.进程优先级.进程组号.当前工作目录.根

Linux fork()、exec() Hook Risk、Design-Principle In Multi-Threadeed Program

目录 1. Linux exec指令执行监控Hook方案 2. 在"Multi-Threadeed Program"环境中调用fork存在的风险 3. Fork When Multi-Threadeed Program的安全设计原则 4. Fork When Multi-Threadeed Program Deaklock Demo Code 1. Linux exec指令执行监控Hook方案 1. 基于LD_PRELOAD技术的glibc API劫持Hook技术 1) 优点: 位于R

以python代码解释fork系统调用

import os print('Process (%s) start...' % os.getpid()) # Only works on Unix/Linux/Mac: pid = os.fork() print ("haha") if pid == 0: print('I am child process (%s) and my parent is %s.' % (os.getpid(), os.getppid())) else: print('I (%s) just creat