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权限

相关推荐
大树8810 小时前
金刚石散热越强,管路越先见顶
大数据·运维·服务器·人工智能·ai
摇滚侠10 小时前
Linux CentOS7 rpm 安装 MySQL 5.7
linux·运维·mysql
霸道流氓气质10 小时前
领域驱动设计(DDD)在 Spring Boot 微服务中的实践指南
运维·spring boot·微服务
bush410 小时前
嵌入式linux学习记录十四、术语
linux·嵌入式
载数而行52010 小时前
Linux 11 动态监控指令top
linux
小宇宙Zz11 小时前
Maven依赖冲突
java·服务器·maven
Inhand陈工11 小时前
基于台达PLC与映翰通IG502的智慧水产养殖精准投喂与远程运维解决方案
运维·人工智能·物联网·阿里云·信息与通信
酣大智12 小时前
ARP代理--工作原理
运维·网络·arp·arp代理
不会C语言的男孩12 小时前
Linux 系统编程 · 第 8 章:进程基础
linux·c语言
shushangyun_12 小时前
2026年快消品B2B系统推荐:支持终端门店订货、促销政策自动化的工具?
java·运维·网络·数据库·人工智能·spring·自动化