Linux 操作系统 进程(2)

上篇文章我们说过的操作系统进程的概念等(Linux 操作系统 进程(1)-CSDN博客),这篇我们就来了解进程最重要最直观的两个状态 :进程状态 进程优先级

进程状态

kill命令

我们在查询进程的时候就可以看到当前进程的状态 " "+"号 在进程状态信息中表示该进程属于前台进程组,即与当前终端相关联的进程组。不加就代表在后台运行,我们怎么让自己的程序在后台运行呢?

cpp 复制代码
//使用死循环,保证程序不会因为自己原因退出
#include<unistd.h>    
#include<stdio.h>    
  
int main()    
{    
    while(1)    
    {    
        sleep(5);                                                                                                                            
    }    
    
    return 0;    
}  

当我们直接运行时

符合我们预期,使用ps来查看他的进程状态

也就是说,我们直接运行程序,我们的程序都是在前台运行,当我们运行程序的时候加上 &

我们可以看到,程序给了我们一段数字,当我们使用ps查询时,

这段数字就是进程的PID,我们会发现,进程的运行状态后面没有" + "号了,这个进程不与终端交互,但是 ,我们该如何 " 杀死 " 这个进程呢 ,由上面死循环程序可以知道这个进程是不会自己退出的,Kill命令就可以做到,因为我们前面让程序在后台运行时,得到了程序的PID,我们可以直接 kill + PID

直接杀死进程

我们同样可以使用man命令查询kill的其他用处,或者是 kill -l查询

进程状态在Linux系统中的定义

在Linux对PCB的定义中可以看到

cpp 复制代码
struct task_struct {
	volatile long state;	/* -1 unrunnable, 0 runnable, >0 stopped */
	...
}

state就是进程的运行状态,Linux中定义了表示各种状态的宏

cpp 复制代码
#define TASK_RUNNING        0x0000  // 运行态
#define TASK_INTERRUPTIBLE  0x0001  // 可中断的睡眠态
#define TASK_UNINTERRUPTIBLE 0x0002 // 不可中断的睡眠态
#define TASK_STOPPED        0x0004  // 停止态
#define TASK_TRACED         0x0008  // 被跟踪态
#define EXIT_DEAD           0x0010  // 进程已经结束
#define EXIT_ZOMBIE         0x0020  // 僵尸进程

看着这些宏的定义,看起来跟我们学习的操作系统进程状态的转换并不一样,因为那个只是概念也就是理想的状态,当我们程序运行的时候,为了保护数据,维护进程IO,会多出来很多状态,用于操作系统处理,这些宏并不直观,我们可以使用这段代码直观解释

cpp 复制代码
/*
* The task state array is a strange "bitmap" of
* reasons to sleep. Thus "running" is zero, and
* you can test for combinations of others with
* simple bit tests.
*/
static const char * const task_state_array[] = {
"R (running)", /* 0 */
"S (sleeping)", /* 1 */
"D (disk sleep)", /* 2 */
"T (stopped)", /* 4 */
"t (tracing stop)", /* 8 */
"X (dead)", /* 16 */
"Z (zombie)", /* 32 */
};

R(running) :程序运行的状态或者说是程序处于运行队列时的状态,不必多说 。

X(dead) :程序死亡。

S(sleeping):

概念意义上的阻塞状态,等待资源的过程,但是这个S可以被杀死,这个等待是操作系统层面的,是等待操作系统的资源,比如我们可以让进程等待我们输入数据 scanf

其实,我们的进程大多数时间都是在等待资源,cpu运行速度太快,我们很难能观察到运行状态,所以我们很多时候查看进程都是S状态。

D(disk sleep)

**等待硬件上的IO,或者说是等待硬件的资源,这个等待无法被打断,防止存储的数据丢失,**操作系统在运行的时候,资源不够的情况下会把一部分处于等待状态的进程" 杀掉 " (杀后台),用来给正在运行的程序或者说是优先级较高的程序分配资源,如果我们的进程正在与硬件进行IO,这时候被操作系统或者说kill命令" 杀掉 ",很大可能导致数据的丢失,而D状态就是为了避免这时候被操作系统" 杀掉 "

T (stopped)

阻塞状态,暂停进程,我们可以通过 kill 命令对其实现暂停

t 状态是程序调试的时候,现在一般理解与T,都是停止状体

Z(zombie)

僵尸进程,当子进程退出时,父进程不对子进程退出的状态进行接收,那么子进程就处于僵尸进程状态,维护退出状态需要数据维护,也属于进程信息,就保存在进程PCB里,如果进程一直不退出,这段PCB就需要操作系统一直使用资源维护,也就是资源浪费,那么父进程创建很多子进程但是不回收,就会浪费很多系统资源,就类似于指针指向的空间不释放,或者说是文件一直被打开,就是属于内存泄漏,这就需要父进程去接受子进程的退出信息。

孤儿进程

也就是父进程比子进程先退出,那么就需要进程去接收这个子进程的退出信息,那么当这个进程退出时,就会被其他**父进程(也就是1号进程)**领养,退出信息也就被这个进程回收

cpp 复制代码
#include<unistd.h>    
#include<stdio.h>    
    
    
int main()    
{    
    pid_t id = fork();    
    
    if(id<0)    
    {    
        perror("进程创建失败");    
        return 1;    
    }    
    else if(id==0)//子进程    
    {    
        sleep(10);    
    }    
    else{    
        sleep(5);//父进程    
    }    
                                                                                                             
    return 0;    
}    

当父进程先退出后,子进程的PPID就变成了 1 号进程

进程优先级

一个进程在cpu上分配资源的前后就是进程的优先级,那么也就是说进程优先级高的会先执行,那么跟操作系统有关的进程先执行,可以大大改善操作系统的性能

查看优先级

PRI:就是进程优先级,NI(nice)就是优先级修正值,也就是说PRI的值越小,进程优先级越高,进程会先被配资源,先执行,那么系统给我们修正值的原因就是我们的程序,也可以通过更改NI来控制部分程序的优先值,让我们认为重要的程序先执行,但是这需要root权限

相关推荐
运维-大白同学6 分钟前
将django+vue项目发布部署到服务器
服务器·vue.js·django
糖豆豆今天也要努力鸭14 分钟前
torch.__version__的torch版本和conda list的torch版本不一致
linux·pytorch·python·深度学习·conda·torch
烦躁的大鼻嘎22 分钟前
【Linux】深入理解GCC/G++编译流程及库文件管理
linux·运维·服务器
乐大师23 分钟前
Deepin登录后提示“解锁登陆密钥环里的密码不匹配”
运维·服务器
ac.char29 分钟前
在 Ubuntu 上安装 Yarn 环境
linux·运维·服务器·ubuntu
敲上瘾29 分钟前
操作系统的理解
linux·运维·服务器·c++·大模型·操作系统·aigc
长弓聊编程1 小时前
Linux系统使用valgrind分析C++程序内存资源使用情况
linux·c++
cherub.1 小时前
深入解析信号量:定义与环形队列生产消费模型剖析
linux·c++
梅见十柒1 小时前
wsl2中kali linux下的docker使用教程(教程总结)
linux·经验分享·docker·云原生
Koi慢热1 小时前
路由基础(全)
linux·网络·网络协议·安全