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。

  • 相关阅读:
    [转载]centos 6.4中git如何正常显示中文
    [转载] 在Linux中,开机自动运行普通用户的脚本程序
    elasticsearch中的filter与aggs
    GET和POST的区别
    Java NIO读书笔记2
    Java NIO读书笔记
    java之并发
    java中参数传递
    java中final关键字
    Java类的初始化过程及清理
  • 原文地址:https://www.cnblogs.com/kkshaq/p/4600836.html
Copyright © 2011-2022 走看看