进程控制之fork()与vfork()函数

6. C++通过fork的方式实现高性能网络服务器 我们上一节课写的tcp我们发现只有第一个与之连接的人才能收发信息。他又很多的不足。 阅读详情

fork()与vfork()函数

标签 : 进程控制


大部分来自书上的知识, 然后在网上有些查了掉, 自己再整理了下, 相当于复习, 也写了点自己的理解,不多.

进程标识符

进程的ID总是唯一的, 所以我们可以将其用作其他标识符保证其唯一性。即,我们在获取进程的ID,也就能够确定其进行的任务, 可以查看进程,也可以杀死进程。(杀掉僵尸进程)
当一个进程终止的时候, ID也就被系统收回, 可以用ID代表其他的进程( 其ID就成了复用的候选者)。 但是,系统采用延迟复用算法, 新建的进程不会立刻使用刚终止的进程的ID, 这是为了防止新进程被误认为使用同一ID的某个已终止的先前进程。

  1. 交换进程(ID=0) : ID为0的进程通常是调度进程(也就是被称为交换进程).该进程是内核的一部分, 它不执行磁盘上的程序, 因此也被称为系统进程.
  2. init进程(ID=1) : init进程是程序自举过程结束由内核调用. 它一般读取与系统初始化文件有关, 并把系统引导到一个状态, 所以他不会终止.(它是所有成为孤儿进程的父进程)
  3. 守护进程(ID=2) : 此进程负责支持虚拟存储系统的分页操作.

fork()函数

pid_t fork(void)

1.返回值:
子进程返回0
父进程返回子进程的ID
错误,返回-1
2.没有固定的先后顺序, 可能先执行父进程,也可能先执行子进程. 这个要看系统的调度. 3.子进程会复制父进程的数据空间, 堆栈段. 但是父子进程都共用一个正文段.
fork()后面接一个exec(), 将采用写时复用. 段只读 即, 子进程不会复制父进程的所有能复制的数据,而是与父进程共用一个副本数据, 当要修改某段数据的时候才复制这个数据段, 提高了效率。
4.父进程打开文件描述符也会被子进程复制, 他们共享一个文件表项
子父进程处理同一个文件就像是原子操作, 同一时刻只能处理一个相同部分(即, 不能同时修改同一个地方)

不管使用哪种线程库, fork()创建的子进程只保留调用线程的副本。

/*************************************************************************
    > File Name: fork__缓冲.cpp
    > Author: Function_Dou
    > Mail: 
    > Created Time: 2018年01月31日 星期三 17时36分30秒

     strlen()与sizeof()的区别:
         strlen() : 采用函数进行遍历得到长度, 并且不包含NULL
         sizeof() : 调用的是缓冲区已知字符串的初始化, 长度是固定的, 但是要包含NULL

 ************************************************************************/

#include <stdio.h>
#include "apue.h"

int num = 10;
char ch[] = "write :";

int main(void)
{
    int var;
    var = 0;
    pid_t pid;

    if(write(STDOUT_FILENO, ch, sizeof(ch) -1) != sizeof(ch) - 1)
        err_sys("write error");

    printf("printf\n");

    if((pid = fork()) < 0)
        err_sys("fork error");
    else if(pid == 0)
    {
        var++;
        num++;
    }
    else    
        sleep(2);
    printf("num = %d\nvar = %d\n", num, var);

    exit(0);
}

/*    样例 : ./a.out 
write :printf 
num = 11
var = 1
num = 10
var = 0

[root@192 Process]# ./a.out > temp
[root@192 Process]# cat temp 
write :printf 
num = 11
var = 1
printf
num = 10
var = 0
*/
在此可以看出,
write两次不同的测验都只输出了一次,printf输出的次数不同.
1. 采用./a.out输出是因为此时缓冲采用的是行缓冲, 所以当输出printf后exit(0)会将其缓冲冲洗, 而重定向文本就是采用的全缓冲, 所以printf没有被冲洗掉.
2. write()函数是不带缓冲的, 所以只会输出一次
子父进程的参数不一样, 因为子进程拷贝了一份数据段, 所以数据也就不同是应当的.

同理, 我们也可以修改一下代码就可以看到不同的结果, 由此来验证exit(), _exit()的不同, 虽然之前说过, exit()会执行清理操作, 在进入内核, _exit()直接进入内核.

/*****************  第一次修改  ******************/
// 删除exit(0), 加上
_exit(0);

/*****************  第二次修改  ******************/
// 删除exit(0), 加上
if(pid == 0)
    exit(0);
else
    _exit(0);

vfork()函数

vfork()函数用于创建一个新的进程,新进程的目地是exec一个新的程序.

  • vfork()调用时与父进程共用同一个段, 修改数据会直接影响到父进程的数据, 段将不是只读;
  • vfork()当调用exec()函数时, 将创造新的进程, 不再共享段. 相当于写时复制
  • vfork()函数讲明确先进行子进程, 在进行父进程, 不会象fork()函数不确定(fork()要看系统调度)
/*************************************************************************
    > File Name: vfork__缓冲.cpp
    > Author: Function_Dou
    > Mail: 
    > Created Time: 2018年01月31日 星期三 20时03分55秒
 ************************************************************************/

#include <stdio.h>
#include "apue.h"

int val = 10;

int main()
{
    int num;
    num = 0;
    pid_t pid;

    printf("vfork:\n");
    if((pid = vfork()) < 0)
        err_sys("vfork error");
    else if(pid == 0)
    {
        val++;
        num++;
        _exit(0);
    }

    printf("pid = %d\nval = %d\nnum = %d\n", pid, val, num);


    exit(0);
}
/*    样例
 *
[root@192 Process]# ./a.out
vfork:
pid = 14178
val = 11
num = 1

[root@192 Process]# ./a.out > tep
[root@192 Process]# cat tep
vfork:
pid = 14197
val = 11
num = 1
*/

可以看出来, 在子进程修改的数据影响到了父进程的数据, 两个都是共用段的(没有调用嗯exec时)
当将_exit()改为exit()结果也不会变, 因为exit()会冲洗缓冲, 所以还是只有一句vfork.
(可做修改进行验证)

/***********************  修改1  *******************************/

  // 删除_exit(0);加上
  exit(0);

/************************  修改2  *******************************/

  // 删除_exit(0)

我不知道markdown导出到csdn有些代码有高亮有些没有。

Linux系统编程(vfork和fork) 本篇文章讲解vfork和fork创建进程的区别。本篇文章讲解了vfork的具体操作和内部含义,并且将vfork和fork进行了对比。 阅读详情

相关推荐

不修改MMDetection源码使用自定义数据和模型

以目标检测为例,用非侵入式的模型和MMDetection数据的方法进行配置。也就是不改动MMDetection的任何源码或目录的条件下,使用自定义数据训练自定义模型。

Dlite的技术笔记 1341

(C++通讯架构学习笔记):fork函数详解、范例演示

目录 fork()函数简单认识 僵尸进程的产生、解决,SIGCHLD fork()函数进一步认识 完善一下fork()代码 fork()失败的可能性 fork()函数简单认识 创建进程 进程的概念:一个可执行程序,执行起来就是一个进程,再执行起来一次,它就又是一个进程(多个进程可以共享同一个可执行文件)。 文雅说法:进程 定义为程序执行的一个实例。 在一个进程(程序)中,可以用fork()创建一个子进程,当该子进程创建时,它从fork()指令的下一条(或者说从fork().

baidu_41388533的博客 3374

R语言TCGA数据下载避坑指南:biolinks包实战中的5个常见错误与解决方案

本文详细介绍了使用R语言的TCGAbiolinks包下载TCGA数据时常见的5个错误及其解决方案,包括安装与加载问题、查询构建参数设置、下载中断处理、数据加载格式不匹配以及版本兼容性问题。通过实战案例和代码示例,帮助生物信息学研究者高效获取TCGA数据,避免常见陷阱。

weixin_30892037的博客 84

fork函数详解(fork就是分叉的意思, 很形象)

转载地址:http://blog.sina.com.cn/s/blog_7582409f0100v6cp.html

认知 行动 坚持 1万+

微信支付V2,jsapi支付拉起收银台报错:调用支付JSAPI缺少参数:total_fee

拉起收银台报错

m0_54355172的博客 3873

洛谷 P5736 【深基7.例2】质数筛

题目描述 输入 n(n\le100)n(n≤100) 个不大于 100000 的整数。要求全部储存在数组中,去除掉不是质数的数字,依次输出剩余的质数。 输入格式 无 输出格式 无 输入输出样例 输入 #1 复制 5 3 4 5 6 7 输出 #1 复制 3 5 7 板子题,使用一下线性筛 #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using n

qq_37978559的博客 1117

C++进程和fork

简单介绍进程和C++的fork函数

qq_44875284的博客 3589

博途WinCC多语言项目配置指南

在博途(TIA Portal)中为WinCC项目配置多语言功能,需通过系统化步骤实现界面文本的动态切换。

dhaimo的博客 2472

多线程 --- fork()、vfork()函数(底层解析)

fork()函数 头文件 #include<unistd.h> #include<sys/types.h> 函数原型 pid_t fork( void); (pid_t 是一个宏定义,其实质是int 被定义在#include<sys/types.h>中)返回值: 若成功调用一次则返回两个值,子进程返回0,父进程返回子进程ID;否则,出错返回-1 函数说明 fork一个现有进程可以调用fork函数创建一个新进程。由fork创建的新进程被称为子进程(child process

demo_yo的博客 425

同花顺PC端逆向解析:Hook注入与加密破解实战指南

在Windows客户端数据采集场景中,当常规HTTP爬虫失效时,内存级逆向分析成为获取实时行情数据的关键路径。其核心涉及进程注入、运行时解密、反调试绕过等底层技术,本质是理解PE加载机制、函数调用约定与内存保护策略的协同过程。同花顺作为典型加固客户端,采用ASPack加壳+自研解密+多线程校验三重防护,迫使开发者转向APC注入、动态密钥提取与XXTEA算法复刻等高阶手段。本文聚焦于DLL注入选型依据、解密函数定位方法及二进制Blob结构化解析,最终实现从内存读取到Pandas DataFrame的端到端数据

weixin_32234493的博客 1200

python爬虫豆瓣读书top250+数据清洗+数据库+Java后端开发+Echarts数据可视化(二)

之前的博客已经写了python爬取豆瓣读书top250的相关信息,接下来继续看如何清洗数据。 如果有没看懂的或是不了解上一部分说的是什么内容的,请看https://blog.youkuaiyun.com/qq_45804925/article/details/112848887 现在开始具体内容的复习: 1. 豆瓣读书top250信息预处理 #数据清洗 import pandas as pd import re import time # 先读取数据文件 data = pd.read_csv('E:/Class/商.

qq_45804925的博客 4442

多进程之创建子进程fork,vfork函数

本博文讲解的是关于进程的创建;首先我们要先知道什么是进程和进程的一些知识 1.进程:是一个正在运行时的程序,系统会给这个程序分配一些系统资源,例如:内存,管理文件的结构体等。。。 2.程序:是由编译器编译后生成的可执行文件 3.所有进程都是由一个进程ID号为 0 的祖宗进程创建出来的 4.一个进程里面可以包含多个线程 5.进程是系统管理分配资源的最小单位 6.线程是系统调度的最小单位 , 7.如果父进程在创建子进程出来后就先运行结束了,子进程就会失去它原来的父进程,系统就会找一个进程来给这个子进

takashi77的博客 1733

基于深度学习YOLOv8的PCB板缺陷检测系统

基于YOLOv8的PCB板缺陷检测系统,可以有效提高PCB生产过程中的检测效率。未来,我们可以进一步优化模型,结合更多的数据增强策略和先进的网络结构,以适应更复杂的生产环境。为了进行训练,理想的数据集应包含多种不同缺陷类型和不同背景的PCB图像。YOLOv8需要的数据格式为每个图像一个标签文件,每个标签文件包含缺陷的类别及其边界框坐标。运行该界面时,用户可以通过点击按钮选择图像,随后系统将自动检测图像中的PCB缺陷并显示结果。训练完成后,可以使用训练好的模型进行推理,检测新的PCB图像中的缺陷。

YOLO 1070

fork()与vfork()

linux进程学习笔记--fork()函数与vfork()函数

qq_49042913的博客 470

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

fork()创建进程原理

深入介绍了Linux系统的系统调用fork()的底层原理:包括写时复制机制,fork()和vfork()的区别,创建进程和线程的区别,fork()创建子进程各个阶段做的事情

mrqiuwen的博客 2659

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

fork()和vfork()的区别

  getpid()函数;   作用:返回当前进程的进程ID;   头文件#include&lt;unistd.h&gt; fork():  作用:创建子进程; 返回值==0:表子进程;  &gt; 0:父进程,且返回值是子进程的ID;  == -1:出错;    运行结果:    分析:因为父进程中pid = fork(),fork返回的是其子进程的ID;所以上图...

kuimzzs的博客 390

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

【Linux】进程控制(创建, 终止, 等待, 程序替换)

目录 进程控制 进程创建 fork() vfork() fork 与 vfork的区别 进程终止 进程终止的场景 : 进程终止有三种方式 : 进程退出返回值 进程等待 为什么要进行进程等待? 进程等待的方法 获取进程退出返回值 程序替换 替换函数 具体替换 : 进程控制 进程控制大概分为 : 进程创建, 进程退出, 进程等待,...

卑微楽的开发之路 557

进程控制(2):进程操作

前言: 关于进程控制这块的好文很多,下面转载的这篇内容很丰富,也会举适当的栗子,与其写的一知半解不如参读学习别人的优秀博文,感谢原作,本系列摘录自:https://www.cnblogs.com/xiaomanon/p/4195327.html。如果有不妥之处,请告知,会删除的,再次感谢o(*^▽^*)┛ 进程控制(2):进程操作 进程(英语:process),是计算机中已运行程序的实体。进...

码码的小海绵 398

linux进程操作相关函数,Linux进程控制简介与要素及相关函数详解

进程是操作系统中的一个重要概念,它是一个程序的一次执行过程,程序是进程的一种静态描述,系统中运行的每一个程序都是在它的进程中运行的。进程4要素要有一段程序供该进程运行进程专用的系统堆栈空间进程控制块(PCB),具体实现是task_struct结构有独立的存储空间Linux系统中所有的进程是相互联系的,除了初始化进程外,所有进程都有一个父进程。新的进程不是被创建,而是被复制,或是从以前的进程复制而来...

weixin_39927408的博客 254

Linux进程控制:fork与exec系统调用详解

进程控制是操作系统核心功能,Linux通过fork()和exec()系统调用实现进程创建与程序加载。fork()采用写时复制技术高效创建子进程,而exec()则实现进程映像的替换。理解这些系统调用的工作原理对开发高性能服务、实现进程池等场景至关重要。在服务器编程中,合理使用fork-exec模式能有效提升并发处理能力,同时需要注意避免僵尸进程、资源泄漏等常见问题。本文通过代码示例演示了Linux进程控制的典型应用场景与最佳实践。

weixin_30527423的博客 372

linux 进程控制总结笔记

关于linux 高级编程中进程的控制总结 进程ID是进程的一个基本属性,下面介绍进程中六个重要的ID,及获取的函数原型 说到进程,我们该怎么创建进程呢?这里使用fork()函数创建进程。 上面所说fork函数创建父子进程,他们是相互独立的,那怎么创建一个共享空间的子进程呢?下面用类似fork函数的vfork()函数实现: Linux环境下使用exec函数执行一个新程序 wait函数的使用,僵尸进程的危害及如何避免僵尸进程的产生呢?

dancersky的博客 634

linux进程控制

进程控制    ps 可以查看进程,默认情况下只能当前终端启动的进程。    ps -ef 可以查看所有进程(Unix/Linux)    ps -aux 也可以    ps -aux是Linux特有的命令,Unix不直接支持。/usr/ucb/ps 支持。    Unix命令:     | more 可以分页显示结果,回车滚动一行,空格翻过一页,q退出。    ps -aux |

254

fork创建子进程

这几天在看看笔试题,准备找移动开发的,找到了百度 济南移动终端开发的笔试题,一看吓一跳,很多都忘了,就目前的情况,基本都不会,赶紧拿来以前的笔记,复习一下。  以下是百度济南的笔试题:    1  .利用互斥量和条件变量设计一个消息队列,具有以下功能:      (1)  创建消息队列(消息中所含的元素)       (2)消息队列中插入消息       (3)取出一个消息(阻塞方式)

1743

进程创建大盘点

程序崩溃是因为 vfork() 后,子进程和父进程共享同一个进程空间,第 31 行,子进程 return 0 之后,会从创建点返回,破坏栈结构,使得父进程的栈空间被破坏掉,从而导致程序崩溃。我们在 fork() 之后,立即执行 execve() 的话,fork() 复制父进程进程空间的操作是多余的,因为 execve() 会覆盖复制出来的父进程进程空间。vfork() 后,子进程共享父进程的地址空间,父进程会等待子进程运行结束后,再向下运行。子进程可以使用父进程的数据 (堆,栈,全局)

qq_52484093的博客 209

Linux系统编程——进程控制(二)

二 进程的基本操作 相关的函数被定义在系统调用库unistd.h中。 1.fork系统调用 fork系统调用有两个函数,分别是fork()和vfork()函数。可创建一个子进程,调用的一般形式是: pid_t fork(void); pid_t vfork(void); pid_t:用于保存进程PID信息的结构体 调用成功时,对父进程返回子进程PID,对子进程返回0。调用失败时返回-1,子进程...

无夜之凛冬的博客 317

C++之进程与线程编程(2)linux进程控制原语

一个进程的控制过程就是创建,执行,终止。llinux对于这三类控制都有一类函数,叫做进程控制原语。 一、创建原语 1)fork() 2)vfork() 二、执行(加载)原语:exec函数族 1)execl 2) execv 3) execle 4) execve 5) execlp 6) execvp 三、退出/等待原语:exit()函数族,wait函数族 ...

释晓的博客 521
上一篇: 进程环境
下一篇: exit()与wait-()函数
Function_18
博客等级 码龄10年 193粉丝 239原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值