二十一、Linux 进程与信号---进程查看和进程状态、进程调度和进程状态变化、进程标识

21.1 进程查看和进程状态

21.1.1 ps 指令

  ps 指令通常可以查看到进程的 ID、进程的用户 ID、进程状态和进程的 Command

  ps:查看当前用户启动的进程

  

  ps -ef:详细查看后台进程信息,可以用 ps -ef | more 进行分屏查看

  

  ps -aux:当前运行的进程占用的CPU的时间,内存的时间

  

  • USER:进程的属组
  • PID:进程的ID
  • PPID:父进程
  • %CPU:进程占用的CPU百分比
  • %MEM:占用内存的百分比
  • NI:进程的 NICE值,数值大,表示较少占用CPU的时间 
  • VSZ:进程虚拟大小
  • RSS:驻留中页的数量
  • TTY:终端ID
  • WCHAN:正在等待的时间
  • START:启动进程的时间
  • STAT:进程的状态
  • TIME:进程消耗CPU的时间
  • COMMAND:命令的名称和参数 

21.1.2 进程状态

  • linux上进程有5种状态: 
    • 运行(正在运行或在运行队列中等待) 
    • 中断(休眠中, 受阻, 在等待某个条件的形成或接受到信号) ---可中断等待状态
    • 不可中断(收到信号不唤醒和不可运行, 进程必须等待直到有中断发生)---不可中断等待状态 
    • 僵死(进程已终止, 但进程描述符存在, 直到父进程调用wait4()系统调用后释放) 
    • 停止(进程收到SIGSTOP, SIGSTP, SIGTIN, SIGTOU信号后停止运行运行)
  • ps工具标识进程的5种状态码: 
    • D 不可中断 uninterruptible sleep (usually IO) 
    • R 运行 runnable (on run queue) 
    • S 中断 sleeping 
    • T 停止 traced or stopped 
    • Z 僵死 a defunct ("zombie") process

  注: 其它状态还包括W(无驻留页), <(高优先级进程), N(低优先级进程), L(内存锁页).

21.2 进程调度和进程状态变化

21.2.1 进程调度

  进程如何进行调度:

  • 第一步:处理内核中的工作
  • 第二步:处理当前进程
  • 第三步:选择进程
    • 实时进程
    • 普通进程  
  • 第四步:进程交换

  启动进程之后,会启动一个 task_struct 结构体,在此结构体中会存储进程调度的一些信息。task_struct 中的调度信息:

  • 策略
    • 轮流策略
    • 先进先出策略  
  • 优先权
    • Jiffies 变量  
  • 实时优先权
    • 实时进程之间  
  • 计数器

21.2.2 进程状态变化关系

  

21.3 进程标识

  内核通过 PID 来区分不同的进程

 1 #include <unistd.h>
 2 #include <sys/types.h>
 3 
 4 pid_t getpid(void);    //获得当前进程ID
 5 uid_t getuid(void);//获得当前进程的实际用户ID
 6 uid_t geteuid(void);//获得当前进程的有效用户ID
 7 gid_t getgid(void);//获得当前进程的用户组ID
 8 pid_t getppid(void);//获得当前进程的父进程ID
 9 pid_t getpgrp(void);//获得当前进程所在的进程组ID
10 pid_t getpgid(pid_t pid);//获得进程ID 为 pid 的进程所在的进程组 ID
  • 实际用户:即登陆的用户ID,自己的账号登陆系统后,输入 id ,即可查看到自己的用户ID,当前登陆进去的用户即为实际用户。可以用当前用户启动很多进程。
  • 有效用户:在登陆实际用户后,我们仍然可以用不同的用户来启动进程,比如 root 用户。这种就使在执行进程的时候以一种特定的身份去启动,这个身份就是有效用户。一般情况下,有效用户就是实际用户。

 例子:process_id.c

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <unistd.h>
 4 #include <sys/types.h>
 5 
 6 int main(void)
 7 {
 8     printf("pid: %d\n", getpid());//获得当前启动进程的进程编号
 9     printf("uid: %d\n", getuid());//获得当前实际用户的ID
10     printf("ppid: %d\n", getppid());//获得当前执行进程的父进程号
11     printf("euid: %d\n", geteuid());//获得当前有效用户的 ID
12     printf("user gid: %d\n", getgid());//获得用户的组ID
13     printf("gid: %d\n", getpgrp());//获得当前进程组的ID
14     printf("pgid: %d\n", getpgid(getpid()));//获得指定进程的进程组ID
15     printf("ppgid: %d\n", getpgid(getppid()));//获得当前父进程所在的进程组的ID
16 
17     return 0;
18 }

  

  

  当前 ppid 即父进程ID为8468,为当前 shell 的进程

  uid 为用户组 ID,我们当前用户的id 为1000,用户组的 ID 为 1000

  实际用户和有效用户区别:

  查看当前要运行的进程的所在组,可以看见文件的实际用户和实际用户组都为 rk3399

  

  进入 root 模式修改文件的所属组:sudo chown root.root bin/process_id

  

  修改粘着位,通过修改粘着位可以修改启动进程的有效用户:

  sudo chmod u+s bin/process_id //增加粘着位

  s 就是粘着位的设置,为文件添加有效用户

  

  可以看见增加了一个  s,执行权限变为了 s

  运行程序:

  

  可以看见实际用户还是我们当前的用户,有效用户 euid 变为了 root

  当针对文件拥有者本身修改粘着位以后,在运行进程的时候,可以将原先用户的权限(rk3399)提升位文件拥有者(root)的权限。

  

猜你喜欢

转载自www.cnblogs.com/kele-dad/p/9127329.html