【牛客网C++服务器项目学习】Day5-linux下的进程相关

项目学习地址:【牛客网C++服务器项目学习】

day05

1.Linux中查看进程信息

  1. ls /proc/

前面蓝色数字代表的进程的ID。如果你想查看PID为1的进程信息,你需要查看/porc/1这个文件夹

img

  1. 我们也可以使用ps -ef -aux指令来直接显示进程状态或者使用ps aux/auj

  2. top:动态显示进程状态

  3. kill:杀死进程

插一嘴:
今天在腾讯云上开了一个云服务器用于替代VMware虚拟机,由于腾讯云的centos7.6安装的gcc版本为4.8.5,默认不支持c99以后的标准,这带来的问题就是,c99之前的标准不支持在for循环中声明和初始化变量,于是我把centos重装为了8.0,gcc版本为8.2便解决了该问题
但是这样又带来了一个新的问题,vscode的remote远程开发连不上了。这是因为vscode保存了之前连接服务器的ip和密钥,重置了服务器后,需要修改vscode中保存的这部分信息。具体的操作方法请查看这篇文章
vscode配置远程连接失败:过程试图写入的管道不存在(已解决)

2.进程

  1. 进程的创建fork

    1. 详细内容可以看这篇文章Linux下fork函数详解

    2. fork的中文含义是叉子,对应于进程的创建,非常的形象。父进程(一般为执行程序)调用fork函数后,此时程序的执行状态就分成了两个叉子,系统在父进程的基础上,创建了子进程,子进程复制了父进程的所有信息。有区别的是,父进程和子进程的PCB进程号是不同的,每一个进程都有自己独立的进程号。区分父进程和子进程的是fork函数的返回值:在父进程中返回的是子进程的pid进程号,子进程中返回的是0。(fork函数一旦开始执行,系统就会为子进程分配资源,子进程拷贝了父进程的所有信息,父进程和子进程都要继续执行fork函数的相关命令,最后在两个进程中都会有fork函数的返回值。通过返回值区别父子进程)

    3. Linux系统为了追求效率和减少资源浪费。开辟进程时,执行的是:读时共享、写时复制。

  2. GDB调试进程

    1. GDB调试默认跟踪一个进程,父进程。在程序上打断点,只对父进程程序有效,子进程正常运行。如果要设置跟踪子进程,有以下的命令

      1. show/set follow-fork-mode:默认parent,可以修改为child。GDB跟踪子进程,不再跟踪父进程

      2. show/set detach-on-fork:默认on,表示调试时进程分离。设置为off后,未被跟踪的进程阻塞在fork函数处

      3. inferiors:show inferiors,显示调试的进程、inferiors id,切换调试的进程、detach inferiors id,使某个进程脱离调试

  3. exec函数族

  4. 进程退出、孤儿进程、僵尸进程

    1. 进程退出:exit()函数

    2. 孤儿进程:

      1. 父进程运行结束退出,但是子进程还在运行,这样的子进程被称为孤儿进程
      2. 孤儿进程会被内核指定新的父进程为init进程,进程号为1.
    3. 僵尸进程:

      1. 一个进程结束退出后,用户区的数据由当前进程自己释放,归还操作系统、内核区的数据由父进程释放;

      2. 子进程已结束,但父进程迟迟不调用wait函数等去回收子进程的内核区数据,子进程的进程号会一直保存在操作系统中,这样的进程称为僵尸进程

      3. 若产生大量的僵尸进程,就可能没办法创建新的进程,故,僵尸进程不可取。

  5. wait函数

#include <sys/types.h>
#include <sys/wait.h>
pid_t wait(int *wstatus)
  • 作用:回收子进程。父进程执行wait函数后,会立刻阻塞自己,等待子进程的状态转变为僵尸态,回收该子进程,然后父进程继续执行

  • 参数:wstatus

    • 参数可以传递一个int指针,wait函数正确执行后,会将子进程结束的方式传递给这个int指针,通过下面几个函数,可以得知子进程结束的状态:

      • WIFEXITED(status) 这个宏用来指出子进程是否为正常退出的,如果是,它会返回一个非零值。
      • WEXITSTATUS(status) 当WIFEXITED返回非零值时,我们可以用这个宏来提取子进程的返回值,如果子进程调用exit(5)退出,WEXITSTATUS(status) 就会返回5;如果子进程调用exit(7),WEXITSTATUS(status)就会返回7。请注意,如果进程不是正常退出的,也就是说, WIFEXITED返回0,这个值就毫无意义。
    • 参数也可以是传递为值、或者NULL,表示我们不需要记录子进程结束的状态。

  • 返回值:

    • > 0 : 返回子进程的id
    • = -1 :错误,或者没有子进程了
  1. waitpid函数
#include <sys/types.h>
#include <sys/wait.h>
pid_t waitpid(pid_t pid, int *wstatus, int options);
  • 功能:回收指定进程号的子进程,可以设置是否阻塞。

  • 参数:

    • - pid:
      pid > 0 : 某个子进程的pid
      pid = 0 : 回收当前进程组的所有子进程
      pid = -1 : 回收所有的子进程,相当于 wait() (最常用)
      pid < -1 : 某个进程组的组id的绝对值,回收指定进程组中的子进程
    • - options:设置阻塞或者非阻塞
      0 : 阻塞
      WNOHANG : 非阻塞
  • - 返回值:
    > 0 : 返回子进程的id
    = 0 : options=WNOHANG, 表示还有子进程或者
    = -1 :错误,或者没有子进程了

waitpid和wait函数的功能基本上差不多的,最主要的区别在于waitpid可以让父进程不阻塞。

  1. 进程间通信有哪几种方式你知道吗?

img

Linux几乎支持全部UNIX进程间通信方法,包括管道(有名管道和无名管道)、消息队列、共享内存、
信号量和套接字。其中前四个属于同一台机器下进程间的通信,套接字则是用于网络通信。

  1. 无名管道
  • 无名管道特点:

    • 无名管道是一种特殊的文件,这种文件只存在于内存中。其实是一个在内核内存中维护的缓冲器。

    • 无名管道只能用于父子进程或兄弟进程之间,必须用于具有亲缘关系的进程间的通信。

      • 这是因为管道实际上是内存的一个缓冲区,

      • 管道的写入端是一个文件描述符fd[1],对应的是文件x1;

      • 管道的读取端也是一个文件描述符fd[0],对应的文件是x2

      • 在进程之间通过管道通信,实际上是通过缓冲区+两个文件通信。如果两个进程没有关系(父子或者兄弟)则文件描述符对应的文件不是同一个文件,便无法通信。

    • 无名管道只能由一端向另一端发送数据,是半双工方式,如果双方需要同时收发数据需要两个
      管道。

  • 相关接口:

    • int pipe(int fd[2]);

      • fd[2]:管道两端用fd[0]和fd[1]来描述,读的一端用fd[0]表示,写的一端用fd[1]表示。通信双
        方的进程中写数据的一方需要把fd[0]先close掉,读的一方需要先把fd[1]给close掉。
  • 无名管道读写的特点:

    使用管道时,需要注意以下几种特殊的情况(假设都是阻塞I/O操作)

    1.所有的指向管道写端的文件描述符都关闭了(管道写端引用计数为0),有进程从管道的读端
    读数据,那么管道中剩余的数据被读取以后,再次read会返回0,就像读到文件末尾一样。

    2.如果有指向管道写端的文件描述符没有关闭(管道的写端引用计数大于0),而持有管道写端的进程也没有往管道中写数据,这个时候有进程从管道中读取数据,那么管道中剩余的数据被读取后,
    再次read会阻塞,直到管道中有数据可以读了才读取数据并返回。

    3.如果所有指向管道读端的文件描述符都关闭了(管道的读端引用计数为0),这个时候有进程
    向管道中写数据,那么该进程会收到一个信号SIGPIPE, 通常会导致进程异常终止。

    4.如果有指向管道读端的文件描述符没有关闭(管道的读端引用计数大于0),而持有管道读端的进程也没有从管道中读数据,这时有进程向管道中写数据,那么在管道被写满的时候再次write会阻塞,直到管道中有空位置才能再次写入数据并返回。

总结:
读管道:
管道中有数据,read返回实际读到的字节数。
管道中无数据:
写端被全部关闭,read返回0(相当于读到文件的末尾)
写端没有完全关闭,read阻塞等待
写管道:
管道读端全部被关闭,进程异常终止(进程收到SIGPIPE信号)
管道读端没有全部关闭:
管道已满,write阻塞
管道没有满,write将数据写入,并返回实际写入的字节数

Guess you like

Origin blog.csdn.net/qq_42518941/article/details/121804223