进程(一):进程介绍与相关函数

一、进程的概念

1、进程和程序的区别:

程序:是静态的,就是个存放在磁盘里的可执行文件

进程:是动态的,是程序的一次执行过程。
进程是有生命周期的,随着程序的开始而开始,随着程序的结束而结束。
进程是最小的分配资源单位

2、进程的组成

进程包含三部分: 进程的PCB(task_struct结构体)、数据段、程序段。

创建一个进程,操作系统为该进程分配一个task_struct来标识它,同时给它分配4G的虚拟内存空间(3G用户空间,1内核空间),只要进程执行结束,分配给它的资源都会被回收。

进程=task_struct+4G(虚拟内存)
、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、

PCB(Process Control Block,进程控制块): 
PCB是操作系统用来表示进程的数据结构,包含一个进程的所有状态信息。通常包括以下部分:

 - 进程标识符:用于唯一标识一个进程(pid)
 - 处理器状态信息:包括程序计数器、寄存器、堆栈指针等,用于表示进程在CPU上的执行状态
 - 进程调度信息:包括进程优先级、状态(运行、就绪、阻塞等)、调度策略等,用于操作系统调度进程
 - 内存管理信息:包括进程的地址空间、页表等,用于描述进程在内存中的布局
 - 资源管理信息:包括打开的文件描述符、信号量、消息队列等,用于管理进程所使用的系统资源
 - 其他信息:如进程创建时间、执行时间、进程间通信信息等

2.1、PCB结构体成员pid

PID:进程的唯一标识符(进程号)(PCB结构体成员之一)
它是一个大于等于0的整数,在一个系统中能够创建最大的进程号可以通过命令查看是131072个。
在系统下的/proc文件中有正在运行的进程号,进入进程号目录下打开status,里面就是进程的详细信息.

2.2、特殊的pid进程

0(idle):也称为swapper进程,在操作系统启动的时候就已经创建的进程,0号进程是1号进程和2号进程的父进程。

1(init):1号进程 是 0号进程通过kernel_thread函数创建的,它主要是用来在启动的时候初始化各种硬件,硬件初始化完之后,init进程为孤儿进程回收资源。

2(kthreadd):2号进程也是0号进程通过kernel_thread函数创建,是调度器进程。

3、进程的状态

在这里插入图片描述

1. 进程的状态
    D: //不可中断的等待状态
    R: //运行态 running
    S: //可中断的等待态
    T: //停止态
    X: //死亡态
    Z: //僵尸态
2. 进程的附加状态
    <: //高优先级的进程
    N: //低优先级的进程
    L: //内存锁定
    s: //会话组组长
    l: //进程包含多线程
    +: //前台进程

3.1、特殊的进程状态

  • 孤儿进程: 父进程死了之后,子进程就变为孤儿进程(由1号进程回收资源)。

  • 僵尸进程: 子进程死掉之后,父进程没有为子进程回收资源(收尸),这个时候子进程变为僵尸进程。

4、进程相关命令

4.1.ps命令:

ps -ef    //查看所在运行的进程  主要查看进程的父子关系
    UID         PID   PPID  C STIME TTY          TIME CMD
    root          1      0  0 Oct29 ?        00:00:11 /sbin/init auto noprompt
    root          2      0  0 Oct29 ?        00:00:00 [kthreadd]
    root          4      2  0 Oct29 ?        00:00:00 [kworker/0:0H]
    root          6      2  0 Oct29 ?        00:00:00 [mm_percpu_wq]

//UID:用户名 PID:进程号 PPID:父进程号
//TTY:是否和终端有关联,没有关联就是?

ps -ajx    //查看进程  可以指定名称查看  例如  ps -ajx | grep a.out 查看名为a.out的进程
     PPID    PID   PGID    SID TTY       TPGID STAT   UID   TIME COMMAND
     0      1      1      1 ?            -1 Ss       0   0:11 /sbin/init auto no
     0      2      0      0 ?            -1 S        0   0:00 [kthreadd]
     2      4      0      0 ?            -1 I<       0   0:00 [kworker/0:0H]
     2      6      0      0 ?            -1 I<       0   0:00 [mm_percpu_wq]

//只要新开一个终端就会创建一个会话SID
//一个会话内会有一个前台进程组和多个后台进程组PGID
//进程组内会有多个进程
//TTY 和终端是否有关联
//STAT 进程的状态
//TPGID 如果是-1 代表是守护进程

4.2. top/htop命令

 top/htop命令:动态查看进程状态的命令

4.3. pidof命令

pidof a.out   //查看所有名为a.out的进程的进程号

4.4. kill命令(给进程发信号)

kill –l 列出所有信号
kill -信号号 pid     //发信号

kill -2 pid         //给进程号为pid的进程发送2号信号
kill -9 pid         //杀死程序
kill -19 pid        //停止程序
killall name 根据进程名杀死进程

二、进程的创建(父进程创建子进程)(亲缘进程)

1、fork函数

#include <unistd.h>
函数原型:
    pid_t fork(void);
返回值:
    成功的话,子进程的PID号返回给父进程,0返回给子进程;
    失败的话,-1返回给父进程,子进程不会创建,置位错误码。
#include <stdio.h>
#include <unistd.h>
int main(){
    //创建变量承接fork函数的返回值
    pid_t pid;
    
    //fork函数创建
    pid = fork();			//重点1***************************************************
    
    //创建错误
    if(pid == -1){
        printf("fork error\n");return -1;
    }else if(pid == 0){			//重点2***************************************************
        //pid == 0子进程执行的代码
        printf("tihs is child  process\n");
    }else{					   //重点3***************************************************
        //pid > 0,父进程执行的代码
        printf("this is parent process\n");
    }
    printf("1\n");//这个地方的代码父子进程都会执行//重点4************************************
    return 0;    
}

2、fork创建结构图

fork  n次会产生2^n个进程

3

3、进程注意事项

  • 进程的执行没有先后顺序, 时间片轮询,上下文切换【完全随机】。
  • 父子进程在空间上相互独立。

三、进程相关函数

1、getpid/getppid函数(获取进程号)

#include <sys/types.h>
 #include <unistd.h>

函数原型:
       pid_t getpid(void);
功能、返回值:总是成功,获取当前进程的进程号              

 函数原型
       pid_t getppid(void);
功能、返回值:总是成功,获取当前进程的父进程的进程号

2、exit/_exit函数(退出进程)

#include <stdlib.h>

void exit(int status);
参数:
    status : 进程退出时的状态    
        EXIT_SUCCESS
        EXIT_FAILURE
功能:关闭正在执行的进程
返回值:
    无    
     
exit是库函数。进程结束时会刷新缓冲区。(和标准IO一个等级)   
//--------------------------------------------------------------------------------- 
void _exit(int status)
参数:
    status : 进程退出时的状态    
        EXIT_SUCCESS (0)
        EXIT_FAILURE  (1)  
功能:关闭正在执行的进程    
返回值:无  
     
 _exit是系统调用,进程结束的时候不会刷新缓冲区。 (和文件IO一个等级)

3、wait/waitpid函数(阻塞等待子进程结束,并回收子进程)

#include <sys/types.h>
#include <sys/wait.h>
函数原型:
       pid_t wait(int *status);
功能:
    阻塞等待子进程结束并为其回收资源,防止生成僵尸进程       
参数:
    status: 子进程以什么状态退出   一般写为NULL
返回值:
    如果成功,返回终止子进程的进程ID 失败时,返回-1//-----------------------------------------------------------------------------------
#include <sys/types.h>
#include <sys/wait.h>
函数原型:
	pid_t waitpid(pid_t pid, int *wstatus, int options);
功能:回收指定进程号的子进程,可以设置是否阻塞。
参数:
    - pid:
			pid > 0 : 某个子进程的pid
			pid = 0 : 回收当前进程组的所有子进程    
			pid = -1 : 回收所有的子进程,相当于 wait()  (最常用)
			pid < -1 : 某个进程组的组id的绝对值,回收指定进程组中的子进程
    - options:设置阻塞或者非阻塞
			0 : 阻塞
			WNOHANG : 非阻塞
返回值:
			> 0 : 返回子进程的id
			= 0 : options=WNOHANG, 表示还有子进程或者
			= -1 :错误,或者没有子进程了

4、exec函数族(替换进程)(待补充)

5.示例

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#include <stdlib.h>
int main(){
    pid_t pid1, pid2;

    
    //第一个子进程
    if((pid1 = fork())== 0){
        sleep(3);
        printf("1: child process 1\n");
        exit(0);
        
        printf("1: child process 2\n");
    }else{//父进程
        if( (pid2 = fork()) == 0)//第二个子进程
        {
            sleep(1);
            printf("2: child process 1\n");
            while(1);
            exit(0);
        }else{
            wait(NULL);
            wait(NULL);
            printf("3: parent process 1\n");
            printf("3: parent process 2");
        }
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

好好睡觉好好吃饭

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值