【Linux】进程

发布时间:2024年01月16日

进程的概念

进程是被加载到内存中运行的一个程序。

在Linux中,触发任何一个事件的时候,系统都会将其定义为一个进程。执行一个程序或是命令就会触发一个事件从而开启一个进程,而每个进程都有一个独一无二的标识,叫PID。

同时根据触发这个进程的用户与相关属性关系,给这个PID一组有效的权限设置,这个PID能在系统赏执行的操作与权限有关。

程序一般为二进制程序,一般放置在物理磁盘中,当有用户执行时加载到内存中成为一个个体,系统根据执行者的权限与属性分配权限以及PID,这就是进程。

而常驻在内存中的进程被称为服务。

进程相关指令

ps

ps 将某个时间点的进程运行情况截取下来

通常我们用ps搭配的选项常用的就两种:

查看系统所有的进程(没有-,不过Ubuntu中实测加上也可以)
ps aux

仅查看与自己相关的进程
ps -l

?如果我们要找某个进程,我们通常会搭配grep管道符来查找,例如:

kill

kill -signal PID? ? ? ? ? ? ? ? ? ? ? ? 给内核发送一个信号

其中signal可以输入数字来表示不同的信号,PID为被操作的进程的PID。

signal完整的含义可以通过下面两种方式查看:

kill -l

man 7 signal

常用的有下面几个:

1重新启动
2????????等于【ctrl】+【c】来中断进程运行
9强制中断进程
15以正常方式终止进程
19等于【ctrl】+【z】来暂停进程运行

系统编程

#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

以下为系统编程的函数,因此如果使用man来查看详细用法的话需要在man后加上2的选项,例如:

man 2 fork

fork

创建一个子进程,在fork调用的时候,内存中发生了一件事,那就是当前这个执行文件完完全全的复制了一份,如下图所示

?接下来内存里的两个文件(父子进程)会接着执行fork下面的代码。

fork这个函数会返回一个pid,在父进程中返回的是子进程的pid,在子进程中返回的是0,所以我们可以在fork之后通过判断返回值来分别编写父进程与子进程分别进行的操作。

  1 #include <unistd.h>
  2 #include <sys/types.h>
  3 #include <sys/wait.h>
  4 #include <iostream>
  5 using namespace std;
  6 int main(void){
  7     cout<<"hello world!"<<endl;
  8     pid_t pid=fork();
  9     if(pid==0){
 10         cout<<"this is son"<<endl;
 11     }else{
 12         cout<<"this is father"<<endl;
 13         wait(NULL);
 14     }
 15     cout<<"procedure over"<<endl;
 16     return 0;
 17 }

可以看出hello world打印了一次,而procedure over 打印了两次。这是因为子进程复制出去之后仅仅执行fork之后的代码,虽然子进程拥有fork之前的代码,但是是不执行的。

getpid/getppid

调用pid可以获取当前进程的pid。

调用ppid可以获取当前进程的父进程的pid。

  1 #include <unistd.h>
  2 #include <sys/types.h>
  3 #include <sys/wait.h>
  4 #include <iostream>
  5 using namespace std;
  6 int main(void){
  7     cout<<"hello world!"<<endl;
  8     pid_t pid=fork();
  9     if(pid==0){
 10         cout<<getpid()<<' '<<getppid()<<endl;
 11     }else{
 12         cout<<getpid()<<' '<<getppid()<<endl;
 13         wait(NULL);
 14     }
 15     return 0;
 16 }

wait/waitpid

wait可以回收一个子进程,waitpid可以回收特定pid的子进程。

如果使用了多线程,父进程执行完毕,而子进程还没有执行完,那么子进程就变成了孤儿进程,没有父进程为其回收,最终init进程会变成孤儿进程的父进程。

而子进程执行完毕,而父进程还没有为子进程进行回收的工作,那么子进程就会变成僵尸进程,占用内存资源。

为了防止这两种情况的发生,我们需要在父进程中调用回收函数。

wait会阻塞程序,直到子进程结束,然后将其回收。wait有一个传出参数,可以通过宏函数(详情使用man来查看)来操作这个传出参数得到子进程的状态。

waitpid可以指定需要回收的子进程的pid,并且除了传出参数,还多一个选项,可以选择是否阻塞。

参考:

《鸟哥的LINUX私房菜基础学习篇(第四版)》?

黑马程序员Linux系统编程课程

文章来源:https://blog.csdn.net/m0_63235356/article/details/134494404
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。