zoukankan      html  css  js  c++  java
  • fork()父子进程文件描述符的关系

    父子进程共享文件描述符:此说法,其实是父子进程共享 文件表项(父进程和子进程共享同一个file table entry)

    由于子进程是父进程的拷贝,子进程会拷贝父进程的进程描述符中的文件描述符表,可以说继承父进程的文件描述字(files_struct中的struct file *fd_array[NR_OPEN_DEFAULT]的拷贝)

    如果我们没有调用exec函数,则我们父子进程的代码段,堆栈,数据段都完全相同(因为是拷贝),所以此时我们的子进程可以使用fork()之前的fd值,虽然此时fd是属于子进程的数据段(他是之前fd的拷贝)

    一个进程一旦调用exec类函数,它本身就"死亡"了,系统把代码段替换成新的程序的代码,废弃原有的数据段和堆栈段,并为新程序分配新的数据段与堆栈段,唯一留下的,就是进程号,也就是说,对系统而言,还是同一个进程,不过已经是另一个程序了。(不过exec类函数中有的还允许继承环境变量之类的信息。)

    所以进程的存储映像被新程序代替(也就是说,含有对方地址的套接字地址结构也丢失了),但是由于即便exec之后,打开的文件描述符依然存在,所以我们可以通过调用getpeername(fd.....)获得对端的ip和端口号

    一般来说:调用exec之前在进程中打开的描述字在exec之后还是保持打开状态的,我们可以通过fcntl函数设置FD_CLOEXEC描述字标志来关闭。此又称为文件描述字标签,默认情况是清除的

    由于exec之后,原来connfd描述字肯定没有了,所以我们必须还原这个connfd

    1、把connfd当成一个字符串,作为exec的命令行参数给新程序

    2、在调用exec之前,把某个描述字设置成connfd,(通过close(fd),然后调用dup(connfd),则根据规则,使用最小未被使用的fd,及是fd,这样fd就和connfd一样指向同一个文件表项),通常我们用0,1,2设置成connfd。

  • 相关阅读:
    mysql常用基本命令
    mysql8.0.13下载与安装图文教程
    k8s ingress 增加跨域配置
    Jenkins 备份恢复插件 thinBackup 使用
    k8s HA master 节点宕机修复
    nginx 跨域问题解决
    mongodb 3.4.24 主从复制
    k8s 线上安装 jenkins并结合 jenkinsfile 实现 helm 自动化部署
    k8s helm 运用与自建helm仓库chartmuseum
    centos6 源码安装 unzip
  • 原文地址:https://www.cnblogs.com/kkshaq/p/4600836.html
Copyright © 2011-2022 走看看