系统编程—进程

一、进程的概念

1.程序与进程的区别

        程序:编译后产生的,格式为ELF的,存储于硬盘的文件。可以通过     readelf -s [文件名]   查看文件信息                                                                                                                                                 进程:程序中的代码和数据,被加载到内存中运行的过程。当程序被CPU加载时,根据每一行代码做出相应的效果,形成动态的过程,那么这个过程就是进程。 其实说白了,进程就是一个正在执行的程序。                                                                                                                                          程序是静态的概念,进程是动态的概念

2 .开启进程

直接在linux下,执行一个程序,就会开启相应的进程。

例如: ./main -> 开启一个名字为hello的进程。

3当进程开启之后,系统会为进程分配的资源

(1)会分配进程对应内存空间

int x;   //运行程序后,会向栈空间申请四个字节的空间

(2)进程在系统内核中如何进行表示呢

学生管理系统 ----------->每个学生使用结构体进行表示和管理

     linux系统   ----------->每个进程使用结构体进行表示和管理

当进程开启之后,会为这个进程分配一个任务结构体,这个任务结构体就是用于描述这个进程的。也就是说,进程在内核中是以结构体struct task_struct{} 进行表示的。这个结构体也被称之为进程控制块。

结构体:进程ID号、信号、文件、资源....

/usr/src/linux-headers-3.5.0-23/include/linux/sched.h 

二、关于进程的命令

1.可以使用命令pstree查看这些进程的关系

可以看到,最开始的系统进程叫systemd,这个进程的诞生比较特别,其身份信息在系统启动前就已经存在于系统分区之中,在系统启动时直接复制到内存。

2.ps查看进程ID号

ps -ef/-elf  静态显示

3.top查看进程CPU的占用率

三、进程的状态

1.什么是僵尸态?

进程结束时,就从运行态变成僵尸态,所谓僵尸态,就是代表这个进程所占用的CPU资源和自身的任务结构体没有被释放,这个状态的进程就是僵尸态进程。

2.总结:

1)进程在暂停态时,收到继续的信号时,是切换到就绪态,而不是运行态。

2)程序的main函数执行return 0就会导致进程的退出,一定会变成僵尸态。

3)进程不可以没有父进程,也不能同时拥有两个父进程。

4)孤儿进程特征就是失去父进程时,会马上寻找继父,而不是等到孤儿进程变成僵尸态再找。

5)祖先进程一定要帮其他的进程回收资源。

四、进程的创建

1.创建一个进程

pid_t fork(void);  // 返回值   失败-1

                           // 大于0 id号代表子进程的ID号    =0

结果1:父进程先运行,子进程后运行

在这里,只有父进程退出,才会出现命令行,子进程退出是不会出现命令行

 结果2:子进程先运行,父进程后运行

2.想确保子进程先运行,就要父进程先睡眠

getpid----》返回自己的ID号
getppid---》返回父进程的ID号

五、僵尸进程和孤儿进程

1.概念

        孤儿进程:一般情况下,调用fork()函数创建的子进程,父进程如果比子进程先退出,那么这个子进程称之为 孤儿进程。那么,祖先进程systemd 就会成为该子进程的父进程,回收该子进程的资源。

       僵尸进程:父进程还存在,但是去做的别的事情了(比如在一个死循环,没有退出),此时子进程退出之后,就变成了僵尸进程。
(可以用ps -ef 查看,进程的状态栏为defunct,这就是所谓的“僵尸”进程)

2.僵尸进程

3.孤儿进程

4、解决僵尸态问题

父进程应当调用wait()waitpid()函数来等待子进程的结束,并回收子进程的资源。这是解决僵尸进程问题的最直接方法。

(1)wait()

pid_t wait(int *status);

  • int *status:这是一个指向整数的指针,用于接收子进程的退出状态。这个参数是可选的,如果你不关心子进程的退出状态,可以传递NULL。如果传递了一个非NULL的指针,系统将通过该指针返回子进程的退出状态信息。
  • pid_t:函数返回结束的子进程的PID。如果调用进程没有子进程,则返回-1,并设置errno为ECHILD。如果出现其他错误,也会返回-1,但errno会设置为相应的错误代码。

(2)waitpid()

#include <sys/wait.h>

pid_t waitpid(pid_t pid, int *status, int options);

参数

  • pid:指定要等待的子进程的PID。

    • 如果 pid 大于 0,则等待与 pid 相等的子进程。
    • 如果 pid 等于 0,则等待任何子进程(与 wait() 类似,但具有 options 提供的额外控制)。
    • 如果 pid 等于 -1,则等待任何子进程,其行为与 pid 为 0 时类似,但某些系统实现可能会为 -1 提供不同的处理(如处理孤儿进程)。
    • 如果 pid 小于 -1,则等待组ID等于 pid 绝对值的任何子进程。
  • status:指向整数的指针,用于接收子进程的退出状态。与 wait() 一样,这个参数是可选的。

  • options:一个或多个选项标志的位或(bitwise OR),用于修改 waitpid() 的行为。常见的选项包括:

    • WNOHANG:如果指定的子进程没有结束,则立即返回0,而不是阻塞。
    • WUNTRACED:返回因停止信号而停止的子进程的状态。

      返回值

    • 成功时,waitpid() 返回结束或停止的子进程的PID。
    • 如果 WNOHANG 被设置且没有子进程结束,则返回0。
    • 如果出现错误,则返回-1,并设置errno以指示错误。

六、进程的退出与回收

1、exit()

#include <stdlib.h>

void exit(int status);

  • 功能:终止当前进程,执行清理操作(如调用 atexit() 注册的函数、刷新标准I/O缓冲区),并返回给操作系统一个状态码。
  • 参数int status(整型),表示进程的退出状态码。通常,0 表示成功,非0 值表示某种错误或特定状态。
  • 头文件<stdlib.h>

2._exit()

  • 功能:立即终止当前进程,不进行任何清理操作(如调用 atexit() 注册的函数、不刷新标准I/O缓冲区),并返回给操作系统一个状态码。
  • 参数int status(整型),表示进程的退出状态码。
  • 头文件<unistd.h>(注意,这个头文件在Windows中不可用,是POSIX系统的一部分)

3._Exit()

  • 功能:与 _exit() 类似,立即终止当前进程,不进行任何清理操作,并返回给操作系统一个状态码。它是C99标准中引入的,旨在提供一种可移植的方式来执行 _exit() 的功能。
  • 参数int status(整型),表示进程的退出状态码。
  • 头文件<stdlib.h>(注意,尽管 _Exit() 在 <stdlib.h> 中声明,但它的实现可能依赖于系统调用 _exit(),后者通常在 <unistd.h> 中定义)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天雨~流芳

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值