【Linux-进程1】进程概念

1.什么是进程

  • 进程就是系统运行中的程序(process)进程 = 可执行程序 + 该进程对应的内核数据结构。(2.1)
  • 进程=对应的代码和数据+进程对于的PCB控制块
  1. 进程是计算机科学中的一个基本概念,是指正在执行中的程序实例。本质上,进程是计算机为了管理和调度正在运行的程序而引入的一个概念。它是操作系统为了实现多任务并发执行而采取的一种抽象和管理方式。
  2. 每个进程都有自己的内存空间和寄存器状态,独立于其他进程。操作系统通过进程调度算法来控制进程的执行顺序和时间分配,从而实现多任务并发执行。
  3. 进程的本质是抽象出来的计算机执行单元,它具有一定的生命周期和状态,包括创建、就绪、运行、阻塞和终止等不同阶段。通过操作系统的管理和调度,进程可以与其他进程进行通信,共享资源,实现复杂的计算和操作。
  4. 总之,进程是操作系统中的基本执行单元,是实现并发和多任务的基础。

🌈为何要引入进程

主要是为了实现多任务并发执行,提高计算机系统的资源利用率和运行效率。下面列出了一些引入进程的原因:

  1. 实现并发执行:操作系统可以同时运行多个进程,实现并发执行。这样,用户就可以在同时执行多个任务的同时,不必等待一个任务完成才能进行下一个任务。

  2. 管理系统资源:每个进程有自己的地址空间和寄存器状态,操作系统可以通过管理和调度进程来优化系统资源的利用,避免进程之间的冲突和资源争用。

  3. 提高系统可靠性:如果一个进程崩溃或出现错误,操作系统可以终止该进程而不影响其他进程的运行,提高系统的可靠性和稳定性

  4. 实现进程间通信:操作系统可以提供各种进程间通信机制,如管道、消息队列、共享内存等,使不同进程之间可以进行数据交换和协同工作。

  5. 实现虚拟内存:操作系统可以将进程的虚拟地址映射到物理内存,使得进程可以访问大于物理内存容量的数据,从而提高系统的可用内存大小。

这里有些内容会在后面进行讲解,各位不必着急。

2.进程控制块PCB(process control  block) 

🌈2.1为什么设计进程控制块


一个可执行程序运行之后就变成了一个进程存在于内存里。但是这么多进程操作系统怎么区分哪一个是已经执行过的,那一个是等待执行的,哪一个需要被删除呢?所以就设计出了一种数据结构(struct结构体)来存储一个进程的所以属性。这个数据结构就叫做进程控制块PCB。(task_struct是PCB的一种)

task_struct包含了进程的标识符状态优先级、计数器、CPU寄存器、打开文件等等

  • 所以进程就是上面说的代码数据+ 进程对应的进程控制块。
  • 每个进程都拥有自己的PCB,而一个PCB只能对应一个进程。当一个进程被创建时,操作系统会为其分配一个新的PCB,当进程结束时,PCB也会被销毁。
  • 示例:

你凭什么说自己是你们学校的学生?因为你在学校里?那食堂的工人,保安大爷也在学校里他们也是学生吗?

如果说你是某某大学的学生,那你要能进入学校学习,其次学校要有你的个人档案包括籍贯+学籍+个人履历等等。这两个都齐全才基本说明是这个学校学生。如果小明因为违纪被学校开除,学校是仅仅把他赶出学校吗?也要开除他的学籍,然后赶出校园。

  • 如何管理多进程(先描述再组织

内存中的大量进程被PCB进行描述,然后操作系统在根据PCB描述的信息再把相同描述的PCB组织起来来管理大量进程.

task_struct主要包含以下内容:

  • 进程标示符:描述本进程的唯一标示符(PID),用来区别其他进程。
  • 状态:任务状态,退出代码,退出信号等。
  • 优先级:相对于其他进程的优先级。
  • 程序计数器:程序中即将被执行的下一条指令的地址
  • 内存指针:包括程序代码和进程相关数据的指针,还有和其他进程共享的内存块的指针
  • 上下文数据:进程执行时处理器的寄存器中的数据[休学例子,要加图CPU,寄存器]。
  • I/ O状态信息:包括显示的I/O请求,分配给进程的I/ O设备和被进程使用的文件列表。
  • 记账信息:可能包括处理器时间总和,使用的时钟数总和,时间限制,记账号等。其他信息

3.查看进程

  • 我们先创建一个Makefile文件:创建的是文件不是目录

  • 再创建一个myproc.c文件,再进行make操作。
#include<stdio.h>
#include<unistd.h>
  
  int main()
 {
  
    while(1)
    {
      printf("hello world\n");
      sleep(1) ;
    }
  
    return 0;
  }                                                                                                                                                                      

  • 运行myproc 

  • 就会发现死循环了。
  • 这里我们再创建一个分屏来实现,一定要创建一个分屏,要不以下功能不一定能实现。

[CTRL+C] 结束循环

我们如何显示现在的进程呢?主要有以下办法:

  • 通过ps命令查看进程
  • 通过proc查看

通过ps命令查看进程

ps axj | grep 'myproc'


 这里用myproc是因为我的文件的名字就叫myproc.

通过proc查看进程目录

ls /

  • 注意上面的proc目录,它是一个内存文件系统,里面放的是当前系统实时的进程信息。我们进入此目录看看:

每一个进程在系统中,都会存在一个唯一的标识符,就如同每个学生都有学号一样,而这个唯一标识符在linux称为pid(全称process id),而上面蓝色的数字即为进程的pid。  

  • 我们可以查看你显示出来的所有的title列名称,输入下面的指令:
ps ajx | head -1

  • 这一行显示的就是所有的属性名,我们也可以让他全部显示:
ps ajx | head -1 && ps axj | grep 'myproc' 

 这个pid十分重要。

  • 当我们用ctrl+C结束死循环后

 再执行总命令时:

 此时我们在重新启动这个程序,用我们的top命令试一下:

top命令也可以帮我们显示所有进程。一般top命令用得少,不细讲了。top命令输入Q就退出了 。

我的pid不再是是上面那个,而是32790

 我们可以在目录proc下面查询一下32709此时所有的属性数据就都出现了。

ls /proc/32709

 如果还不懂,在命令后面加上-al

  • exe目录:表示进程对应的可执行程序的磁盘文件。 
  • cwd那个目录:是当前进程的工作路径

4通过系统调用获取进程标示符

🌈什么是进程标识符

  • 进程标识符(Process Identifier,PID)操作系统中用来唯一标识一个正在运行的进程的数字。每个进程都有一个唯一的PID,这个PID是由操作系统内核在进程创建时分配的。通常情况下,PID是一个非负整数,一般的操作系统可以支持多达数千个同时运行的进程。
  • 可以使用操作系统提供的系统调用(如Linux中的getpid()函数)来获取当前进程的PID。PID可以用来识别进程,例如在使用进程管理工具(如任务管理器)时,可以使用PID来查找和操作特定的进程

getpid函数是获取进程的pid,包含两个头文件:#include<unistd.h>#include<sys/types.h>

这里我们在myproc.c文件中在写一个代码:  

然后clean;我们再在右边的程序中make一下,然后运行./myproc 

 根据上面的运行结构可知:运行两次,子进程pid改变。

但是父进程ppid不会改变。

  • 我们可以输入下面的指令来查看这个父进程到底是什么: 
ps ajx | head -1 && ps axj | grep 20505

图中可以看出父进程13009就是一个bash。几乎我们在命令行上所执行的所有的指令,都是bash进程的子进程!  

 

5.通过系统调用创建进程-fork初识

🌈fork函数

fork()函数一在Linux系统中常用的系统调用,用于创建一个新的进程(子进程)。

  • fork()函数被调用时,操作系统会在当前进程的地址空间中创建一个新的进程,并将当前进程的副本(包括代码、数据、堆栈等)复制一份给子进程。这样,父进程和子进程之间就共享同样的代码、数据和打开的文件等信息,但是各自拥有独立的堆栈和寄存器等运行时状态。
  • 父进程和子进程在fork()函数调用后,分别从fork()函数的返回值中得到不同的结果。在父进程中,fork()函数返回新创建子进程的PID(进程标识符),而在子进程中,fork()函数返回0。如果fork()函数调用失败,则返回一个负值。

1.用fork创建一个子进程:

man fork

 退出fork文档用【Q】

fork函数是用来创建子进程的,它有两个返回值:

  • 返回成功的话,把子进程的pid返回给父进程,给子进程返回0
  • 失败的话,-1返回给父进程。不创建子进程
#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
  
  
  int main()
 {
     printf("I am a process : pid: %d\n", getpid());
  
    pid_t ret=fork();    //创建子进程, 一个父进程,一个子进程
    printf("ret %d: pid %d: ppid: %d\n", ret, getpid(), getppid());                                                                                                    
  
      sleep(1);
 
    return 0;
  }

 17742是17741的父进程,因为给父进程返回子进程的pid,同理,下面的是子进程,因为给子进程返回的的是0。


  • 为啥父子进程会返回成功两个返回值呢?代码不都是一个吗?

 

 这个原理是刚开始是父进程,但是经过fork函数后又创建了一个子进程。fork函数之后的代码是父子共享的。所以父子进程同时执行了一遍return。所以打印两次。

  • return返回两次意味着就要保存两次返回值吗?

🌈 父子进程分流

父子进程的内容关系:

  1. 父进程创建子进程,子进程是父进程的一个副本,包括了父进程的代码、数据和堆栈等资源。

  2. 子进程和父进程有各自独立的地址空间和系统资源,例如内存、文件描述符和信号处理器等。就行孩子的DNA大多数和父母一样,但是有自己的不同之处。


  • fork函数之后的代码是父子共享但是创建子进程不是让他俩来执行同一份代码的,而是执行不同命令的。那如何让父子进程执行不同命令?

    虽然代码共享但是这里我们可以根据返回值进行分流。根据子进程的返回值是0分离父子进程。

  • fork()函数后面的内容父子进程共享。

父子进程对于代码是共享的但是并不意味着两者所执行的代码一模一样,因为两者的pid不一样,尽管两者都能看见fork()后的代码但是并不执行同一份代码。

以前c中if,else if只能执行一个,但是这个多进程能同时执行二者而不冲突。

 

总结: 

fork之后,父进程和子进程会共享代码,一般都会执行后续的代码,这就是为什么printf会打印两次的原因。
fork之后,父进程和子进程返回值不同,可以通过不同的返回值,判断,让父子执行不同的代码块。

🐴先运行子进程还是先运行父进程? 

这个根据情况进行判断,但是这么多进程先运行那个是不是需要一种标准来执行?所以为了区分先运行那个,删除那个,退出那个进程操作系统就给它们标记了一种状态。又被称为进程状态。



兄弟们累了就先歇会再学! !!!!!!!

6.进程状态

🌈操作系统进程状态

进程状态本质上就是一个整数,在进程的task_struct。

  • 进程状态反映进程执行过程的变化。这些状态随着进程的执行和外界条件的变化而转换。在三态模型中,进程状态分为三个基本状态,即运行态就绪态阻塞态。在五态模型中,进程分为新建态、终止态,运行态,就绪态,阻塞态

  1. 运行态:进程占有处理器正在运行。
  2. 就绪态:进程具备运行条件,等待系统分配处理器以便运行。
  3. 等待态:又称为阻塞(blocked)态或睡眠(sleep)态,指进程不具备运行条件,正在等待某个事件的完成。

当进程需要被

  • 1、进程运行: 

运行态指的是进程只要在运行队列中就叫做运行状态,它表明进程要么是在运行中要么在运行队列里。代表我已经准备好了,随时可以调度。

  • 2、进程终止:
  1.  这个进程还在,只不过永远不运行了,随时等待被释放!
  2. 进程都终止了,为什么部立马释放对应的资源,而要维护一个终止状态?

 因为即使你进程终止了,但是你操作系统并不能立马就来释放你,就好比如你在一家餐厅的某个位置吃饭,当你吃饭走人后,这个位置能再次被别人使用吗,当然不能,因为服务员还没来得及收拾你的残渣。所以既然你已经终止了,那么就需要一直维持着终止状态,以此告诉操作系统等你不忙了赶紧来把我释放掉,这就是随时等待被释放。 

  • 3、进程阻塞:
等待非CPU资源就绪的状态叫做进程阻塞。
  •   4、进程挂起(也属于S 状态)

内存不足的时候,OS提供适当的置换进程的代码和数据到磁盘中,PCB不换(好比你学籍还在,人把你赶走了)进程的状态就叫做挂起。  你现在正在等待某种资源的时候,正巧内存不足了,内存不够是你正在阻塞状态,所以把你的代码数据置换到磁盘里,所以叫做“挂起阻塞

引起挂起状态的原因有:

  1. 对换的需要。为了缓和内存紧张的情况,而将内存中处于阻塞状态的进程换至外存上,使进程又处于一种有别于阻塞状态的新状态。因为即使该进程所期待的事件发生,该进程仍不具备执行条件而不能进入就绪队列,称这种状态为挂起状态。
  2. 终端用户的请求。当终端用户在自己的程序运行期间,发现有可疑问题时,往往希望使自己的进程暂停下来。也就是说,使正在执行的进程暂停执行,若是就绪进程,则不接受调度以便研究其执行情况或对程序进行修改。把这种静止状态也称为挂起状态。
  3. 父进程请求。父进程常希望挂起自己的子进程,以便考查和修改子进程,或者协调各子进程间的活动。

🌈linux中内核进程状态有:

  • 1、运行状态---R(进程创建+运行)

一个进程处于运行状态(running),并不意味着进程一定在运行中,它表明进程要么是在运行中要么在运行队列里。

while :; do ps axj | head -1 && ps ajx | grep myproc | grep -v grep; sleep 1; done

 状态是S+,而不是R但是并不代表不是运行状态。就是运行的速度太快,打印时还没反应过来就运行完了,就是打印的时间比运行的时间长,所以显示的不是运行状态R。

当我们编译运行此程序后,进入死循环,此程序没有访问其它外设资源(读文件、读磁盘……)此进程一直在cpu的队列里,下面来查看此进程的状态:

 这里为啥还有+?

状态后面带+说明这个任务是前台进程。

什么是前台进程?前台进程一启动,执行命令就没有效果了并且能被ctrl+c终止。

在后面+&就把前台任务改成后台任务了。并且显示了PID。 

  •  前台进程:S+ 和后台进程:S 的区别 

前台进程./myproc,输入指令无效bash的命令行解释器就停止工作了,可以被【Ctrl +C】终止

后台进程./myproc &,可以执行指令,【Ctrl +C】 不能终止进程,退出进程要用kill

  • 2、浅度睡眠状态(sleeping) ---S,也叫做可中断睡眠(interruptible sleep)

 等待非CPU资源就绪。这种休眠是可被换醒的,我们可以 Ctrl + C 退出循环,而此时的进程就没了,也就是说它虽然是一种休眠状态,但是它随时可以接收外部的信号,处理外部的请求。上面的那个S+中的S就是睡眠状态的意思。

  • 浅度睡眠:当进程处于S状态,它可以随时被操作系统唤醒
  • 可中断睡眠:当进程处于S状态,它可以被你随时kill杀掉:
  • 3、 深度睡眠状态(Disk sleep)---D,也叫不可中断睡眠状态(uninterruptible sleep)

进程处于D状态,不可被杀掉,只能等这个进程自动醒来,kill -9 都杀不掉它,也得等它醒来。 (关机除外,有可能关机都要被磁盘写入卡住,只能拔电源)。                                       浅度睡眠和深度睡眠D最大的区别是当OS的内存不够时,OS能杀掉浅度睡眠下的进程,但是不能杀掉D状态的进程。

  •  4、死亡状态(dead)--X

随时准备被OS回收。此状态只是一个返回状态,无法在任务列表中看到这个状态。因为回收进程是一瞬间发生的事情,我们很难直接捕捉到。

  • 5、僵尸状态(Zombie)---Z

一个进程已经退出,但还不允许被OS释放,处于一个被检测的状态。

  1. 在操作系统中,进程完成执行后,需要向其父进程发送一个信号来表明其执行状态的结束。如果子进程结束后,父进程没有接收到这个信号,那么子进程就会变成僵尸进程。
  2. 僵尸进程指的是进程已经结束,但是PCB仍然存在于系统中,因为父进程没有处理完子进程的终止信息。
  • 6、暂停状态 ---T/t

可以通过发送 SIGSTOP(kill -19) 信号给进程来停止(T)进程。这个被暂停的进程可以通过发送 SIGCONT 信号让进程继续运行。暂停状态一般都是在调试时,就比如我们打断点,不是我们让这个程序听了,而是操作系统发送一个信号是程序变成暂停状态。

kill -l

kill -19 PID(自己的)

kill -18 PID

  •  🐴暂停T和睡眠S的区别

暂停停的进程是正在运行的,而睡眠状态的进程如果等待的资源就绪后会被唤醒进入就绪或者运行状态。

🌈内核状态和系统状态区别

最上面我们说了五种(三种)系统的进程状态,像新建,运行,阻塞,挂起等,为啥内核状态没有将这个几个状态而是讲了S.D,X,Z等状态?

其实系统状态适用于各个系统,像Linux,windos 安卓的,它更像状态哲学,说不清道不明。

内核状态是linux根据系统状态为基础实现的适用于linux系统的基础知识。

🌈僵尸进程

僵尸状态是一个进程已经退出但是还是不允许被OS释放,处于一个被检测的状态。僵尸进程是处于僵尸状态的进程。

  • 僵死状态(Zombies)是一个比较特殊的状态。子进程退出并且父进程没有读取到子进程退出的返回代码时就会产生僵死(尸)进程
  • 僵死进程会以终止状态保持在进程表中,并且会一直在等待父进程读取退出状态代码。
  • 所以,只要子进程退出,父进程还在运行,但父进程没有读取子进程状态,子进程进入Z状态

检查端口常用命令:

while :; do ps axj | head -1 && ps axj | grep myproc | grep -v grep; sleep 1; echo "########################"; done
 #include<stdio.h>
  3 #include<stdlib.h>
  4 #include<unistd.h>
  5 int main()
  6 {
  7   pid_t id= fork();                                                                                  
  8   if(id==0)
  9   {
 10     //child
 11     int cnt=5;
 12     while(cnt)
 13     {
 14       printf("我是子进程,我还剩下:%d S\n", cnt--);
 15       sleep(1);
 16     }
 17     printf("我是子进程,我已经是僵尸,等待被检测\n");
 18     exit(0);
 19   }
 20   else
 21   {
 22     //father
 23     while(1)
 24     {
 25       sleep(1);
 26     }
 27   }
 28   return 0;
 29 }

这时就出现了僵尸进程。

🐖僵尸进程的危害: 

  • 僵尸进程虽然不会执行任何代码,也不会占用CPU时间,但是它们仍然会占用系统资源,包括进程ID和一些内存资源等。如果产生大量的僵尸进程,会导致系统资源的浪费,从而影响系统性能。
  • 此外,如果一个父进程创建了很多子进程,但没有正确处理它们的退出状态信息,就可能导致系统中出现大量的僵尸进程。这样会使系统的进程数达到系统能够承受的最大值,从而导致新的进程无法被创建,影响系统的稳定性。
  • 另外,如果系统中存在大量的僵尸进程,攻击者可以利用这些僵尸进程进行攻击,例如通过僵尸进程发起DDoS攻击等。
  • 因此,正确地管理进程的退出状态信息对于避免僵尸进程的产生非常重要。及时清理僵尸进程可以释放系统资源,提高系统的性能和稳定性。

🌈孤儿进程 :

  • 什么是孤儿进程

孤儿进程是指其父进程已经退出或异常终止,但该进程仍在继续运行的进程。孤儿进程不再有父进程,因此它会被init进程(进程号为1)所接管。

我们不妨举例实验一下:

#include<stdlib.h>
  4 #include<unistd.h>
  5 int main()
  6 {
  7   pid_t id= fork();
  8   if(id==0)
  9   {
 10     //child
 11     while(1)
 12     {
 13       printf("hello world!:\n");
 14       sleep(1);
 15     }
 16 
 17   }
 18   else
 19   {
 20     //father
 21      int cnt=5;
 22     while(5)
 23     {
 24       printf("I am father: %d\n", cnt--);                                                                                        
 25       sleep(1);
 26     }
 27   }
 28   return 0;
 29 }

  • 当父进程退出的时候,父进程为什么没有变成僵尸状态Z呢?
  1. 因为父进程的父进程是bash,bash会自动回收它的子进程,也就是这里的父进程,换言之这里没有看到僵尸是因为父进程被它的父进程bash回收了。
  2. 先前我们说过,子进程退出的时候,父进程要通过某种方式回收子进程,但是这里很明显父进程先走了,子进程还没退出,可如果我子进程退出了,那谁来回收我呢?
  3. 总结:这里操作系统就扮演了干爹的角色,也就是如果父进程提前退出,子进程就会被1号进程(就是init进程)领养,我们把这种被领养的进程称为孤儿进程。

🐖孤儿进程为啥被领养 

  • 操作系统将孤儿进程接管,以确保进程能够正常退出并且不会成为僵尸进程。
  • 在Linux系统中,init进程(或其替代者systemd)是所有进程的祖先进程,因此所有孤儿进程最终都会被init进程接管。init进程会周期性地调用wait()系统调用来等待孤儿进程结束,并且释放它们占用的系统资源。因此,将孤儿进程交给init进程接管可以确保系统的稳定性和安全性。
  • 此外,如果一个孤儿进程没有被接管,它就会一直在系统中占用资源,这不仅浪费了系统资源,而且还可能导致系统崩溃。因此,孤儿进程需要被及时接管并退出。

7.进程优先级 

概念:

  1. cpu资源分配的优先顺序,就是指进程的优先权(priority)。
  2. 优先权高的进程有优先执行的权利。配置进程优先权对多任务环境的Linux很有用。
  3. 还可以将进程安排到指定的CPU上,将不重要进程安排到某个CPU,可改善系统整体性能。
  • 由于系统中进程数量众多,而CPU资源比较少甚至只有一个,进程之间需要竞争来使用CPU。这时让一个比较重要、需要优先执行的进程去和其他进程竞争,显然是不合理的。为了更合理的分配CPU资源, 就有了进程优先级。
  • 优先级高的进程有优先执行的权利。此外,优先级还影响分配给进程的时间片长短。 重要的进程,应该分配多一些cpu时间片,好让其尽快完成任务。所有的进程都会有机会运行,但优先级高的进程会获取更多的cpu执行时间。配置进程优先级对多任务环境的Linux很有用,可以改善系统性能。

查看优先级:

ps -l

我们很容易注意到其中的几个重要信息,如下:

  • UID : 代表执行者的身份
  • PID : 代表这个进程的代号
  • PPID :代表这个进程是由哪个进程发展衍生而来的,亦即父进程的代号
  • PRI :代表这个进程可被执行的优先级,其值越小越早被执行
  • NI :nice值, nice 是用来修改 PRI 的 , 也就是说用来调整进程优先级的, PRI(new) = PRI(old) + nice。当nice值为负值的时候,那么该程序优先级会变高 (PRI数值降低)。
  • 需要强调一点的是,进程的nice值不是进程的优先级,他们不是一个概念,但是进程nice值会影响到进程的优先级变化nice值是进程优先级的修正修正数据。

查看优先级的的信息:

 ps -al

调整进程优先级

用top命令更改已存在进程的nice值来调整进程优先级

  • 执行 top 命令。
  • 进入top后输入r ===》输入需要修改的进程的进程号PID ===》再输入nice 的值 , 按回车即可。

4个重要概念:

  1. 竞争性:系统进程数目众多,而CPU资源只有少量,甚至1个,所以进程之间是具有竞争属性的。为了高效完成任务,更合理竞争相关资源,便具有了优先级
  2. 独立性:多进程运行,需要独享各种资源,多进程运行期间互不干扰
  3. 并行:多个进程在多个CPU下分别,同时进行运行,这称之为并行
  4. 并发:多个进程在一个CPU下采用进程切换的方式,在一段时间之内,让多个进程都得以推进,称之为并发

在不同的操作系统中,进程优先级的实现方式和规则可能会有所不同。一般来说,进程优先级通常由操作系统的调度程序根据一些因素动态地计算和分配,例如:

  1. 进程类型:操作系统可能会为不同类型的进程(如实时进程和普通进程)分配不同的优先级。

  2. 进程资源需求:如果一个进程需要更多的CPU时间或其他系统资源,那么它可能会被分配更高的优先级,以确保它能够及时完成任务。

  3. 进程等待时间:如果一个进程已经等待了很长时间,但还没有得到CPU时间片或其他所需的资源,那么它可能会被分配更高的优先级,以确保它能够尽快得到资源并继续执行。

在大多数操作系统中,进程优先级通常是一个整数值,通常从0到最大优先级(通常为255)之间。在某些操作系统中,还可以使用优先级调整值(nice值)来控制进程的优先级,即使没有明确地分配一个数字优先级。

需要注意的是,高优先级的进程并不总是会一直占用CPU时间,因为操作系统也需要考虑其他因素,如IO等,来进行合理的进程调度。

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值