进程

进程和程序
进程时程序的实体化,程序被储存在磁盘当中,当程序被加载到内存当中(执行起来),操作系统利用PCB将进程描述起来,Linux下PCB是:task_struct


task_struct是一种数据结构,用来描述进程,包含进程的各种信息,包括进程号PID 状态 优先级等等很多信息

  9 task_struct包含的信息:
 10 标识符 : pid
 11 状态 : 就绪,运行,睡眠,阻塞等等
 12 I/O状态信息: 进程打开的文件的信息
 13 记账信息 :进程运行时间等
 14 内存指针 : 包括程序代码和进程相关数据的指针,还有其他进程共享的内存块的指针
 15 程序计数器 : 程序中即将被执行的下一条指令(当兵例子)
 16 上下文数据 : 进程执行时处理器中寄存器的数据
 17 优先级 :决定进程被调度的优先级
 18

查看进程
查看进程可以通过/proc系统文件夹来查看

[liu@localhost 进程]$ ls /proc/
1     1959  2463  29    335  5    67   83         diskstats    mdstat        sysrq-trigger
10    1993  2475  3     34   50   68   84         dma          meminfo       sysvipc
11    2     2476  30    35   51   681  9          driver       misc          timer_list
1151  20    2477  3017  36   52   69   91         execdomains  modules       timer_stats
1152  2027  25    3021  37   53   7    92         fb           mounts        tty
12    2045  2504  3022  38   535  70   93         filesystems  mpt           uptime
1201  2059  2519  3091  39   54   71   94         fs           mtd           version
13    2065  2540  31    4    55   72   95         interrupts   mtrr          vmallocinfo
131   2084  2542  3161  40   56   73   97         iomem        net           vmstat
132   2090  2544  3198  41   57   74   98         ioports      pagetypeinfo  zoneinfo
14    21    2546  3199  42   58   75   99         irq          partitions
15    2122  2548  32    429  59   76   acpi       kallsyms     sched_debug
1551  2134  2550  320   43   6    77   asound     kcore        schedstat
1574  2135  2557  3203  430  60   78   buddyinfo  keys         scsi
16    2179  2558  3204  44   61   79   bus        key-users    self
1607  2187  2565  321   45   62   8    cgroups    kmsg         slabinfo
165   22    26    3228  46   63   80   cmdline    kpagecount   softirqs
17    23    2632  33    47   64   81   cpuinfo    kpageflags   stat
18    2332  27    333   48   65   82   crypto     loadavg      swaps
19    24    28    334   49   66   820  devices    locks        sys

查看进程也可以用ps aux 或者 ps -ef

[liu@localhost 进程]$ ps aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.0   2900  1436 ?        Ss   07:17   0:01 /sbin/init
root         2  0.0  0.0      0     0 ?        S    07:17   0:00 [kthreadd]
root         3  0.0  0.0      0     0 ?        S    07:17   0:00 [migration/0]
root         4  0.0  0.0      0     0 ?        S    07:17   0:00 [ksoftirqd/0]
root         5  0.0  0.0      0     0 ?        S    07:17   0:00 [stopper/0]
root         6  0.0  0.0      0     0 ?        S    07:17   0:00 [watchdog/0]
[liu@localhost 进程]$ ps -ef
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 07:17 ?        00:00:01 /sbin/init
root         2     0  0 07:17 ?        00:00:00 [kthreadd]
root         3     2  0 07:17 ?        00:00:00 [migration/0]
root         4     2  0 07:17 ?        00:00:00 [ksoftirqd/0]
root         5     2  0 07:17 ?        00:00:00 [stopper/0]
root         6     2  0 07:17 ?        00:00:00 [watchdog/0]
root         7     2  0 07:17 ?        00:00:00 [migration/1] 

系统调用创建进程fork
形式 : pid_t fork(void);
fork()会创建一个子进程,拥有和父进程相同的资源,包括代码数据等等, 看看man手册对于fork的描述

NAME
       fork - create a child process

SYNOPSIS
       #include <unistd.h>

       pid_t fork(void);

DESCRIPTION
       fork()  creates  a  new process by duplicating(复制) the calling process.  The new
       process, referred to as the child, is an exact duplicate of the calling pro-
       cess, referred to as the parent

子进程与父进程的调用顺序完全随机,由cup和就绪队列的状态所决定
fork创建子进程成功会产生对两个进程产生不同的返回值,对于子进程是返回0,父进程是返回子进程的PID,若是创建进程失败,则返回-1

fork用法举例 :
getpid()可以获得当前进程的pid

  3 #include <stdio.h>
  4 #include <unistd.h>
  5 
  6 
  7 int main(void)
  8 {
  9     pid_t id = fork();
 10     if(id < 0){
 11         printf("failed \n ");
 12             return -1;
 13     }else if(id == 0){
 14         printf("this is child : %d !!! \n", getpid());
 15     }else{
 16         printf("this is parent : %d !!! \n", getpid());
 17     }   
 18     
 19     printf("this is comman : %d !!!\n", getpid());
 20     
 21     return 0;
 22 }   

运行结果 :

[liu@localhost day01]$ make 
cc fork.c -o fork
[liu@localhost day01]$ ./fork 
this is parent : 3322 !!! 
this is comman : 3322 !!!
this is child : 3323 !!! 
this is comman : 3323 !!!

进程状态
进程状态在kernel源码中的定义 :

/*
 * 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 */
"Z (zombie)",    /* 16 */
"X (dead)",    /* 32 */
};
  • R (Runing)运行状态 : 并不意味着进程一定在运行中,它表明进程要么在运行状态中,要么正在运行队列里
  • S((interruptible)Sleeping)(可中断)睡眠状态:意味着进程在等待着事情的完成
  • D(Disk Sleeping)磁盘休眠状态(不可中断睡眠状态):在这个状态的进程通常会等待IO的结束
  • T(Stopped)停止状态:可以发送SIGTOP信号来给进程停止,暂时被停止的进程可以通过发送SIGCONT信号让进程继续运行
  • X(Dead)死亡状态 : 这个状态是一个返回状态,不能再任务列表看到这个状态
  • Z(Zombie)僵尸状态:正常退出失败,即死亡还拥有资源,造成的危害进程状态

系统进程状态的修改
这里写图片描述


僵尸进程状态分析

  • 当前进程退出并且父进程未处理子进程的退出信息或者未接收到退出信息,这时就会产生僵尸进程
  • 僵尸进程会以终止状态保持在进程表里,并且一直等待父进程读取退出状态码

创建一个维持十秒的僵尸进程的例子

  1 #include <unistd.h>
  2 #include <stdio.h>
  3 #include <stdlib.h>
  4 
  5 int main(void)
  6 {   
  7     pid_t id = fork();
  8     if(id < 0){
  9         printf("error\n");
 10         return -1;
 11     }
 12     else if(id == 0)
 13     {   
 14         printf("this is child process\n");
 15         sleep(1);
 16         exit(0);
 17     }
 18     else{
 19         sleep(20);
 20     }
 21     return 0;
 22 }

监视结果,出现Z(僵尸)状态

[liu@bogon day01]$ ps aux | grep js
liu       3750  0.0  0.0   1864   316 pts/1    S+   09:14   0:00 ./js
liu       3751  0.0  0.0      0     0 pts/1    Z+   09:14   0:00 [js] <defunct>
liu       3755  0.0  0.0   4420   772 pts/0    S+   09:15   0:00 grep js

僵尸进程的危害

  • 进程退出状态也需要PCB来维护其数据,若保存Z状态不退出,则会一直要维护PCB造成内存泄漏
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值