Linux 操作系统 进程(2)

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

进程状态

kill命令

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

//使用死循环,保证程序不会因为自己原因退出
#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的定义中可以看到

struct task_struct {
	volatile long state;	/* -1 unrunnable, 0 runnable, >0 stopped */
	...
}

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

#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,会多出来很多状态,用于操作系统处理,这些宏并不直观,我们可以使用这段代码直观解释

/*
* 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号进程)领养,退出信息也就被这个进程回收

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值