美文网首页
信号打断read()函数、accept()函数

信号打断read()函数、accept()函数

作者: StevenHD | 来源:发表于2020-12-07 00:03 被阅读0次

一、信号打断read()函数

  • read()函数如果阻塞地读,很容易就会被信号打断
    如果被信号打断,返回的错误码errno则是EINTR,然而无所谓,我们被信号打断并不影响什么,continue并且取消关闭fd,进入下一次循环即可——
图示代码

二、信号打断accept()函数

  • 先打开服务器后,不启动客户端,那么现在就阻塞在accept()这个地方
  • 打开服务器后,客户端启动完,就进入到了read()函数中

被信号打断并不可怕,我们只要设置成,万一被打断了,重启一次就行,这样就没有事

accept()被打断后的处理
我们可以让它continue,另一种就是设置【信号中的RESTART】——
信号中的重启
  • read函数中的信号处理——


    图示代码

三、复习review

复习大纲
复习大纲2

四、错误值封装

  • 一行的结束标志是/n
  • 字符串的结束标志是/0

先从缓存中读取数据,然后读取文件描述符(套接字)中的数据

五、多进程服务器

多进程模型1 多进程模型2
  • 轮询的坏处:如果没有实际的数据进入,那么CPU就是一直空转,占用CPU的使用

  • 现如今服务器的缺点,不能处理多个客户端的连接,因为accept()完成后,会进入read()函数,这个时候第二个客户端连接进来后只能进入accpe()的队列中,但是服务器还是在read()函数中,没有进入到accept()那个函数,那么就不能处理另一个客户端的三次握手

  • 多进程服务器模型,原先的进程只负责accept(),至于读取数据则是fork()出一个子进程来处理,新来一个客户端的连接就fork()一次子进程——

  • fork()之后文件描述符表也会被复制,因为整个PCB都会被复制,PCB中包含文件描述符表。(fork()之后file结构体并没有复制过来,只是新的FD对应的新的指针指向了同一个file结构体

子进程中的client_fd是从父进程中拷贝过来的,使用这个复制过来的套接字client_fd并读取数据,并且和父进程中的client_fd指向的是同一个套接字socket。

  • 将fork()放到accept()函数的下面,然后将之前的读取数据都放在子进程中,父进程直接continue,进行下一次accept()即可。
图示代码
图示代码2
  • 但是上述代码会产生僵尸进程,我们没有去回收子进程
  • 之前回收子进程的方法有wait()和waitpid(),但是现在父进程已经阻塞在accept()了(每接收完一个请求就回到accept()那里),不能再让它阻塞在wait()那里接收子进程的退出了。

所以除了阻塞轮询的方式,我们只能使用【信号waitpid()】这种方式了——

这样就不会出现僵尸进程了
这样就不会出现僵尸进程了
为什么使用SIGCHLD这个信号呢?因为当子进程退出的时候会发给父进程信号SIGCHLD,所以我们需要捕捉的就是这个信号。
  • 100个子进程同时退出,就会给父进程发100个信号
  • 文件描述符表通过fork()直接复制过来,是一个浅拷贝,并没有生成新的file结构体

因为fork()后不论是listen_fd还是client_fd都会被复制,但是listen_fd并没有再被使用,所以要在一开始就关闭掉listen_fd——

图示代码关闭listen_fd
  • 当然了,因为父进程中没有再用到client_fd,所以在fork()后,也要手动关闭client_fd,因为只有这样才不会造成内存泄漏,只靠子进程那里关闭只会让引用计数-1,并不会真的关闭,除非父进程也退出——
图示代码——父进程也要关闭client_fd

5.1 服务器不光读也可以写消息给客户端

  • 服务器的代码(将接收到的字符串变成大写)——
增加了Write()函数
  • 客户端的代码——
增加了write()和read()函数

多进程模型的好处:可以不断地创建子进程来处理连接请求,可以通过ulimit -a来查看可以创建多少个进程数量

最大进程数量
  • 也可以去系统文件改写这个数值

虽然多进程都是fork出来的,但是比如buf这种缓存区中接收到的内容,因为读时共享,写时复制的原则,buf区中接收到的数据一定是不一样,那么系统会新分配一个内存页的。

相关文章

  • 信号打断read()函数、accept()函数

    一、信号打断read()函数 read()函数如果阻塞地读,很容易就会被信号打断如果被信号打断,返回的错误码err...

  • NIO源码分析(三)

    解释下Channel中accept,read,write中的begin/end函数做了什么 单步跟踪blocked...

  • Elisp一天一函数—— json-read-file

    函数名称:json-read-file 函数原型:(json-read-file FILE) 函数功能一句话描述:...

  • Java面试——TCP/IP

    参考资料:[1]. 网络编程之accept函数和accept函数在三次握手中的位置[2]. TCP 粘包/拆包的原...

  • APUE读书笔记-10信号(4)

    6、可重入函数 进程捕捉到信号时,进程正常执行的指令次序会被信号处理打断。进程会继续执行,但是这时候执行的是信号处...

  • pandas.read_csv

    读取csv文件是遇到了pandas.read_csv函数。下面介绍下这个函数的用法。 pandas.read_cs...

  • linux-10 -信号(2)+IPC

    信号:信号的发送函数/信号集和信号屏蔽/介绍一个sigaction()/信号应用的相关函数:sleep(),usl...

  • select、poll、epoll详解

    IO读写基本原理 用户程序进行IO操作实际依赖于linux系统内核read()、write()函数read()函数...

  • js 调试

    打断点,跟踪函数调用

  • 揭开socket的神秘面纱

    php中socket的应用 php中socket函数 函数名 描述 socket_accept() 接受一个Soc...

网友评论

      本文标题:信号打断read()函数、accept()函数

      本文链接:https://www.haomeiwen.com/subject/nxuowktx.html