fork()子进程与父进程之间的文件描述符问题

linux 子程序文件描述符继承问题 在客户端A操作重启客户端B之后,你会发现,再也无法正确和子进程建立正确的网络连接,而各个子进程的例如心跳包、连接是正常的,不会触发连接状态变化或者网络重连。最近在工作中遇到了一个设计,软件即做服务器,又做客户端,做客户端时跟另外一个服务器建立连接,做服务器时,是与自己启动的几个子进程程序建立连接。而system启动起来的子程序会继承父进程的所有文件描述符,包括套接字,故出现了意想不到的bug。我的应用场景如上图,客户端A的命令通过服务端A的处理之后转发给客户端B,客户端B响应命令开启子进程。 阅读详情
不错的文章,收藏,以备查阅:http://keren.blog.51cto.com/720558/170822

在C程序中,文件由文件指针或者文件描述符表示。ISO C的标准I/0库函数(fopen, fclose, fread, fwrite, fscanf, fprintf等)使用文件指针,UNIX的I/O函数(open, close, read, write, ioctl)使用文件描述符。下面重点来说下,文件描述符是如何工作的。

文件描述符相当于一个逻辑句柄,而open,close等函数则是将文件或者物理设备与句柄相关联。句柄是一个整数,可以理解为进程特定的文件描述符表的 索引。先介绍下面三个概念,后面讲下open、close等操作以后,文件和文件描述符产生什么关系,以及fork后文件描述符的继承等问题。

文件描述符表:用户区的一部分,除非通过使用文件描述符的函数,否则程序无法对其进行访问。对进程中每个打开的文件,文件描述符表都包含一个条目。
系统文件表:为系统中所有的进程共享。对每个活动的open, 它都包含一个条目。每个系统文件表的条目都包含文件偏移量、访问模式(读、写、or 读-写)以及指向它的文件描述符表的条目计数。
内存索引节点表: 对系统中的每个活动的文件(被某个进程打开了),内存中索引节点表都包含一个条目。几个系统文件表条目可能对应于同一个内存索引节点表(不同进程打开同一个文件)。
1、举例: 执行myfd = open( "/home/lucy/my.dat", O_RDONLY); 以后,上述3个表的关系原理图如下:
fork()子进程与父进程之间的文件描述符问题 - HH - 计算机
系统文件表包含一个偏移量,给出了文件当前的位置。若2个进程同时打开一个文件(如上图A,B)做读操作,每个进程都有自己相对于文件的偏移量,而且读入 整个文件是独立于另一个进程的;如果2个进程打开同一个文件做写操作,写操作是相互独立的,每个进程都可以重写另一个进程写入的内容。
如果上面进程在open以后又执行了close()函数,操作系统会删除文件描述符表的第四个条目和系统文件表的对应条目(若指向它的描述符表唯一), 并对内存索引节点表条目中的计数减1,如果自减以后变为0,说明没有其他进程链接此文件,将索引节点表条目也删除,而这里进程B也在open这个文件,所 以索引节点表条目保留。 

2、文件描述符的继承
通过fork()创建子进程时,子进程继承父进程环境和上下文的大部分内容的拷贝,其中就包括文件描述符表。
(1)对于父进程在fork()之前打开的文件来说,子进程都会继承,与父进程共享相同的文件偏移量。如下图所示(0-1-2 表示 标准输入-输出-错误):
fork()子进程与父进程之间的文件描述符问题 - HH - 计算机
系统文件表位于系统空间中,不会被fork()复制,但是系统文件表中的条目会保存指向它的文件描述符表的计数,fork()时需要对这个计数进行维护, 以体现子进程对应的新的文件描述符表也指向它。程序关闭文件时,也是将系统文件表条目内部的计数减一,当计数值减为0时,才将其删除。
(2)相反,如果父进程先进程fork,再打开my.dat,这时父子进程关于my.dat 的文件描述符表指向不同的系统文件表条目,也不再共享文件偏移量(fork以后2个进程分别open,在系统文件表中创建2个条目);但是关于标准输入, 标准输出,标准错误,父子进程还是共享的。
fork()子进程与父进程之间的文件描述符问题 - HH - 计算机
 
 
 原文地址:http://keren.blog.51cto.com/720558/170822
python中fork()函数生成子进程分析 python的os module中有fork()函数用于生成子进程,生成的子进程是父进程的镜像,但是它们有各自的地址空间,子进程复制一份父进程内存给自己,两个进程之间的执行是相互独立的,其执行顺序可以是不确定的、随机的、不可预测的,这点与多线程的执行顺序相似。   import os def child(): print 'A new child:', os.getpid() p 阅读详情

相关推荐

粒子群算法实战:用Matlab解决旅行商问题(TSP)的完整代码解析

本文提供了使用粒子群算法解决旅行商问题的完整Matlab实战指南。通过将连续空间的粒子群算法进行离散化改造,采用基于交换序的策略来更新粒子位置与速度,并给出了从问题定义、数据结构设计、核心函数实现到主迭代循环的详细代码解析。文章还探讨了参数调优、性能优化及处理复杂TSP变体的进阶思路,为物流规划、路径优化等领域的工程应用提供了可直接复用的解决方案。

m2n3o4p5的博客 350

【Linux】文件描述符&先打开open文件再fork&先fork再open

首先,fork创建的子进程的pcb,然后,子进程把父进程的拷贝一份。子进程的file.txt就是拷贝父进程的,也就是他俩共享fork之前的文件描述符。总结:父进程的文件描述符fork以后,子进程也可以访问,而且父子进程共享文件偏移量。(父进程打开一个文件,fork之后的子进程也可以使用,父子进程共享) 补充:在这种情况下,共享偏移量,如果父子进程共同编写文件会出错,因此,父进程一般情况下把文件给子进程,子文件编写。

qq_53830608的博客 1198

Python+ArcGIS实战:5步搞定土壤类型预测(附随机森林模型配置技巧)

本文详细介绍了如何结合Python与ArcGIS,利用随机森林模型进行土壤类型预测。通过5个核心步骤——数据预处理、样本创建、模型构建、空间预测与精度验证,构建了一套自动化、高精度的空间预测工作流,并提供了关键的模型配置与调参技巧,助力GIS开发者高效完成土壤制图任务。

weixin_29227585的博客 396

【Linux】关于fork后exec子进程继承父进程文件描述符保持开放的问题

https://www.cnblogs.com/SebastianHan/p/12469915.html 在多进程编程中,根据业务需要会通过fork+exec执行shell脚本或其它程序,在fork后父、子进程对于每一个打开的文件描述符共享同一个文件表项,此时可能有多个文件描述符项指向同一文件表项。有时子进程不需要继承父进程的文件描述符,并且在exec后子进程继承下来的文件描述符成了耗费系统资源的一个累赘,此时应该怎么处理呢?接下来我将分享下我在工作中遇到的问题以及解决方案。 ...

m0_46535940的博客 1056

从Gcode命令看3D打印机的‘大脑’:Marlin/Klipper固件是如何执行你的指令的?

本文深入解析3D打印机固件Marlin和Klipper如何执行Gcode指令,从语法解析到运动控制算法,再到温度管理,详细揭示了从指令到物理动作的转化过程。通过对比两大固件的设计哲学和性能优化技巧,帮助用户更好地理解和调优3D打印机的核心控制系统。

weixin_26763955的博客 382

深入C++学习还必须掌握的一基础知识精讲

施磊C++语言基础提高课程笔记,包括了new/delete;malloc/free;引用和指针;const,指计和引用的结合;函数重载,inline的数,参数带默认值的函数;函数模板等知识点

GeniusAng的博客 1479

父子进程间文件共享

fork函数调用一次,返回两次。在新创建的过程中返回一次,返回值为0.在原来的进程中返回一次,返回值是新进程的pid。 通过fork函数创建的进程为新进程的父进程。即就是,通过fork创建的进程与原进程是父子关系。孤儿进程:当父进程结束以后,子进程未结束,子进程的父进程变为init。init这个进程是守护进程,它负责处理这些孤儿进程退出以后的一些状态。 僵死进程:(1)父进程未结束,子进程结束,

静沐暖阳的博客 2450

Ubuntu零基础入门到精通【3.10讲】:旧版本 Ubuntu 升级与迁移路线:从 20.04 到 24.04 的完整实战指南

🏆 本文收录于 《滚雪球学 Ubuntu》 专栏。 本专栏面向有一定计算机基础,但尚未系统学习 Linux / Ubuntu 的读者,采用“滚雪球式学习法”:先装好、再会用、再理解、再优化、再实战,带你从第一次进入 Ubuntu 桌面 / 终端开始,逐步掌握 Ubuntu 的日常使用、命令操作、软件安装、系统配置、开发环境搭建与服务器部署能力。

**My Coding Family** 1249

fork()子进程与父进程之间的文件描述符问题 www.educity.cn/linux/1241859.html

在C程序中,文件由或者文件描述符表示。ISO C的标准I/0库函数(fopen, fclose, fread, fwrite, fscanf, fprintf等)使用文件指针,UNIX的I/O函数(open, close, read, write, ioctl)使用文件描述符。下面重点来说下,文件描述符是如何工作的。  文件描述符相当于一个逻辑句柄,而open,close等函数则是将文件或者物理设

诺尔曼 783

5、快速入门

点击启动实例按钮,并设计一个business key,每个实例会有一个business key, 业务主键,也相当于一个流程实例唯一key,一般会与一次业务强相关,比如一个订单号 ,此处取为shopping_1;付款程序完成后会流转到物流发货任务,此时java工程的相应订阅会收到任务,并进入断点,且读到到toWhere变量。单击shopping可以进入实时流程图的执行图,此时流程流转到第一个任务,需要业务系统完成此任务,并通知引擎。添加类,分别订阅流程中的加入购物车任务和物流发货任务。

leyoliu的博客 3502

基于YOLO的智能视频监控异常行为检测研究:从算法原理到落地部署的全栈实践

本文深入探讨如何利用 YOLO(You Only Look Once)系列算法构建一套端到端的异常行为检测系统。文章首先回顾 YOLOv8 在时空建模上的局限,然后提出“YOLO-STA(Spatio-Temporal Aggregation)”轻量级改进框架,在公开数据集 UCF-Crime 上将异常行为检测的 mAP@0.5 从 72.4 提升到 80.1;接着给出完整训练、推理、部署的 Python 代码(PyTorch + TensorRT),并介绍如何仅用 4 GB 显存的 Jetson Xavi

博客 1335

进程(二)—— fork()创建子进程

上一次说明了进程是怎么被创建的,进程的程序又是如何运行的,本文主要介绍fork()函数创建进程的过程中发生了什么,结合代码进行过程分析

challenglistic的博客 1万+

VMware Horizon 8 2111 部署系列(九)创建即时克隆桌面池

即时克隆桌面池是在 vCenter Server 中使用 vmFork 技术(称为即时克隆 API)从最佳配置映像创建的自动桌面池。即时克隆共享同一个基础映像虚拟机,使用基础映像虚拟机的快照创建的,它使用的存储空间也少于完整虚拟机。 即时克隆始终保持开机状态,并在注销后从当前发布的映像重新创建。...

白昼的技术专栏 4043

4.父进程和子进程

父进程和子进程                                子进程是父进程的复制品Unix/linux系统中的进程创建是这样的,理解起来有点绕。父进程先执行fork()系统调用,这个调用的结果是系统中多出了一个跟父进程内容完全一样的进程,这个新进程被称为子进程,当然该进程的PCB中父进程指针是指向第一个进程的。前后两个进程各自有自己的地址空间,形式上有点像把一个文件拷贝了一个副本...

郑学炜的技术博客 3万+

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

创建进程fork——父进程与子进程

fork创建进程 fork系统调用是用于创建进程的,并且fork创建的进程初始化状态与父进程一样。(进程空间中的变量)系统会为fork的进程分配新的资源 fork系统调用无参数。 fork返回两次,(在父进程中)第一次返回子进程id,(在子进程中)第二次返回0 .换句话说就是返回子进程id的是父进程,返回0的是子进程。 测试代码 ...

jane_6091的博客 7618

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

fork()子进程与父进程的关系(继承了什么)

之前发过一篇博客**fork函数详解** #include<stdio.h> #include<string.h> #include<stdlib.h> #include<unistd.h> void main() { char str[6]="hello"; pid_t pid=fork(); if(pid==0...

qq_22613757的博客 6744

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

fork调用后,子进程与父进程是否共享变量

回顾fork调用 fork系统调用从已存在的进程中生成一个新的进程,这个新的进程就是子进程,我们可以通过fork系统调用的返回值来区分子进程还是父进程。 一个进程,包括代码、数据和分配给进程的资源。fork()函数通过系统调用创建一个与原来进程几乎完全相同的进程。 我们的问题是,进程中的变量是否由父进程和子进程共享? 背景 最开始我简单的认为,似乎是看视频里说的。对于只读变量,父

浅浅的i的博客 1万+

fork出的子进程和父进程

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

西红柿爱炒番茄 5524

fork()函数创建子进程

APUE–fork()函数介绍 文章目录APUE--fork()函数介绍一、fork()系统调用介绍1.fork()创建子进程特点2. 子进程的特点二、代码示例1.fork()创建子线程2.子进程对内存修改 一、fork()系统调用介绍 1.fork()创建子进程特点 fork()用于创建子进程,一次调用会有两个返回(return),一次返回给父进程子进程的PID(Process ID),一次返回给子进程,其返回值为0. 返回值=0,子进程在运行 返回值>0,父进程在运行 返回值<0,fo

qq_47834139的博客 7224

在用fork创建子进程时,getppid()返回的却不是父进程的pid,或getppid()返回1。

在学习fork时,了解了子进程与父进程的概念,打算敲代码来实践认识一下。发现了一个很奇怪的问题,使用fork()之后,父进程中pid返回值是子进程,但是子进程中调用getppid(),得到的返回值却不是父进程。 我们先来复习下 fork(),getpid()和getppid()三个函数: 查看manual page: fork: pid_t fork(void); //creates a...

Oerror_的博客 3438

Linux 的父进程和子进程的执行情况(附有案例代码)

该文章主要是针对面试做大致的了解,通俗易懂!!!指已创建一个或多个子进程的进程。在Linux里,除了进程0以外的所有进程都是由其他进程使用系统调用fork()函数创建的,这里调用fork()函数创建新进程的进程即为父进程,而相对应的为其创建出的进程则为子进程,因而除了进程0以外的进程都只有一个父进程,但一个进程可以有多个子进程。指的是由另一进程(对应称之为父进程)所创建的进程。子进程继承了对应的父进程的大部分属性,如文件描述符。在Unix中,子进程通常为系统调用fork()函数的产物。在此情况下,子进程一开

热爱数据库的小胖 8509

fork()函数,fork()子进程父进程的比较总结,fork()与vfork()的比较总结

进程创建fork() fork()函数以父进程为蓝本复制一个进程,其ID号与父进程ID号不同,内存等与父进程不同,其他与父进程同享,只有在父进程或者子进程进行了修改后,才重新生成一份。 成功时,fork返回是进程ID,失败返回-1; #include<sys/types.h> #include<unistd.h> pid_t fork(void) for k()...

weixin_42904113的博客 990

fork之后子进程到底复制了父进程什么

作者:狂奔的乌龟 来源:优快云 原文:https://blog.youkuaiyun.com/xy010902100449/article/details/44851453 #include<stdio.h> #include<string.h> #include<stdlib.h> #include<unistd.h> void main...

一直走,不要回头 2993

P10 Linux进程编程 fork创建子进程

🎬 个人主页:@ChenPi🐻推荐专栏1: 《》✨✨✨🔥 推荐专栏2: 《》✨✨✨🛸推荐专栏3: ​​​​​​《》 ✨✨✨🌺本篇简介 : 上一章我们讲了Linux进程的概念以及获取进程ID号和获取父进程的ID这一章我们引进新的概念,父子进程Linux 是一个多用户多任务的操作系统,每个用户可以同时运行多个程序进程是程序运行的主体,包括进程的创建,调度和消亡的整个过程当用户执行一个指令或者启动一个程序时,就创建了一个进程一个运行的程序也可能有多个进程。每个进程将被分配各种资源。

weixin_73901182的博客 1222

在父进程fork子进程的继承资源的弊端和解决方法

在父进程通过system()函数创建或fork创建子进程时,子进程会继承父进程的资源,包括文件设备访问权限、文件描述符等。这些资源在父子进程交互或共享提供便利的同时也带来了一些弊端,fork会导致 file->count++, 在父进程 close的这些文件设备时候发现还是别的地方对这些文件设备使用,就不会release,导致父进程重新open的时候就会出现"Cannot o...

chengf223的博客 2533
上一篇: struct timeval结构体 以及 gettimeofday()函数
下一篇: dup and dup2的剖析
行知2014
博客等级 码龄19年 8粉丝 12原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值