TCP\IP网络编程学习笔记(四)

  1. 通过fork函数创建的子进程能够继承父进程中所有变量的值,但是一旦创建后,父进程和子进程中的变量不再有任何关系,即使是一个全局变量,父进程和子进程都会有不同的副本,修改并不会影响另一个进程中的这个全局变量的值;

  2. 产生僵尸进程的原因:

    • 子进程使用exit()函数返回一个返回码(即exit()函数里面传入了实参);
    • 子进程main函数(每个进程最后都会从main函数正常返回的啦)通过return语句返回一个值。

    其根本原因是上述两种情况都会将返回的值传给操作系统,而操作系统不会销毁子进程,直到把这些值传递给产生该子进程的父进程(更准确的说是在父进程未收到子进程的返回值前,子进程的进程号的信息仍然保留在系统的进程表里面)。处在这个状态下的进程就是僵尸进程。也就是说,将子进程变成僵尸进程的正是操作系统;

  3. 如何销毁僵尸进程:

    • 通过在父进程里面调用wait()函数,来等待子进程的结束并获取子进程的返回值。这是阻塞函数;
    • 通过在父进程里循环调用waitpid()函数,来获取指定子进程的返回值或者任意子进程的返回值。此函数可阻塞也可非阻塞;
    • 通过使用signal()sigaction()来注册子进程销毁时的信号处理函数,然后在信号处理函数里面使用waitpid()来销毁对应的僵尸进程;
    • 使用双fork()的方式,将真正使用的子进程创建为父进程的孙子进程,然后将父进程的儿子进程使用waitpid()销毁,这样,孙子进程的父进程就会变成init进程。当此孙子进程结束时,init进程会自动调用相关的wait函数,来销毁对应的僵尸进程。
  4. wait()waitpid()异同:

    这两个函数都可用来阻止僵尸进程的存在。

    • wait()是阻塞函数,waitpid()可以以非阻塞方式运行;
    • wait()不能指定子进程,只能等待任意的子进程结束。waitpid()可以指定销毁哪个子进程对应的僵尸进程;
    • wait()成功时返回已结束的子进程ID,失败时返回-1。waitpid()成功时返回已结束的子进程的ID或者0(0表示没有任何子进程结束或者指定的子进程还未结束),失败时返回-1。
  5. signal()sigaction()异同:

    两个都是注册信号处理函数的函数。

    • signal()的兼容性没有sigaction()强,建议使用后者,前者很少用了;
    • 前者使用简单,后者使用需要定义一个sigaction结构体;
    • 它们都可以获取之前注册的信号处理函数的指针,前者使用返回值的方式获取,后者通过最后一个新参的方式获取(不想获取时传入nullptr)。
  6. 如果一个套接字的文件描述符被复制到多个进程空间中,则每个进程空间都要把它复制的那一份文件描述符给close掉,否则,最后对应的套接字无法销毁(就像是加了引用计数一样,只有当套接字的引用计数为0时才销毁套接字)。此外,只有当套接字真正被销毁时,才会给对方发送EOF,如果一个套接字被多个文件描述符所共享,则只close其中一个副本,不会发送EOF,只有最后一个指向此套接字的文件描述符被close时,才会发送EOF。此外,可以直接通过调用shutdown()函数来显式的发送EOF

  7. 通过fork()复制的socket文件描述符指向同一个socket,socket本身并没有被复制。同样,通过fork()复制的管道文件描述符也对应着同一对管道,管道本身并没有被复制。它们都属于操作系统的,不属于进程空间的。此外,子进程中应该主动关闭被赋值过来的但是不需要的文件描述符。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值