Linux应用层开发 --- 多任务

多任务:让程序具备同时处理多个任务的能力(并发)

如何实现多任务:多进程、多线程

(一)进程

1.什么是进程

进程:正在执行的程序,需要消耗内存和CPU

进程和程序的区别:

(1)程序是一组数据指令集和,存储在硬盘空间,是静态的

(2)进程存储在内存空间,执行过程需要CPU参与(内存+CPU)

(3)进程具备动态生命周期,从启动到消亡

(4)程序运行起来产生一个进程,也可产生多个进程

(5)在一个进程中也可以执行多个程序

2.进程的创建

./a.out -----> 启动进程

进程在被创建的时候,操作系统会为该进程分配0-4G的虚拟内存空间

进程是操作系统资源分配的最小单位

3.进程的调度

  • CPU调度进程:宏观并行、微观串行(并发)

并行:多个任务同时执行

  • CPU调度算法:

(1)时间片轮询算法

(2)先来先服务、后来后服务算法

(3)高优先级优先执行算法

(4)短作业优先算法

4.进程的状态

操作系统进程状态三态图:

Linux操作系统进程状态及转换关系:

(1)运行态(用户运行态、内核运行态) R

正在执行,且被CPU任务调度所执行的进程

(2)就绪态 R

正在执行、没有CPU任务调度执行的进程(只缺少CPU)

(3)可唤醒等待态 S

也称为睡眠态、阻塞等待资源的进程

(4)不可唤醒等待态 D

不想被CPU任务调度所打断的进程任务可以设置不可唤醒等待态

(5)暂停态 T

被暂停执行的进程

(6)僵尸态 Z

进程执行结束,空间没有被回收

(7)结束态 X

进程执行结束,空间被回收

S+:处于可中断睡眠状态的前台进程

S:处于可中断睡眠状态的后台进程

T:处于暂停态的后台进程

与终端相关联的多为前台进程

5.进程的消亡

(1)进程退出

  • 进程执行结束退出
  • 主函数中遇到return退出
  • exit() 、_exit() 、Exit(),结束进程

#include <stdlib.h>

void exit(int status);

功能:退出一个进程

参数:

status:进程结束时的状态

0:正常退出

!0:因为其他原因退出

#include <unistd.h>

void _exit(int status);

#include <stdlib.h>

void _Exit(int status);

  • 通过信号结束一个进程(kill -9 进程ID)

(2)进程回收

僵尸进程和孤儿进程

  • 僵尸进程:进程已退出,但其资源空间没有被其父进程回收

如何避免僵尸进程产生:

1)由其父进程对僵尸态进程进行回收:wait()、waitpid()

2)让进程成为一个孤儿进程,结束后,由操作系统回收

  • 孤儿进程:父进程先结束,其父进程创建的子进程成为孤儿进程,将会被系统进程所收养,结束后,由系统进程回收。比j如:守护进程

6.进程相关命令

(1)ps -aux

查看操作系统所有进程的相关参数:PID(进程ID)、创建者、状态、CPU占有率、内存占有率等

ps -aux | grep ./a.out:利用管道符查找某指定名称的进程

| :管道:将前面的输出作为后面的输入

grep:字符串查找

(2)ps -ef

查看操作系统所有进程的相关参数:PID、PPID

父进程:创建新进程的进程是该新进程的父进程(PPID:父进程ID号)

子进程:创建出来的新进程是子进程(PID:Process ID 进程ID号)

(3)top

动态查看进程的状态及CPU占有率、内存占有率

(4)pstree

以树状形式查看进程间的创建关系(族谱图)

pstree -sp:以树状形式查看,带ID号

pstree -sp 进程ID:查看指定ID的进程的创建关系

(5)kill

kill -信号名称/信号ID PID:给PID对应的进程发送一个信号

kill -l:查看系统定义出来的信号

kill -9 进程ID:结束一个进程(杀死进程)

常用:9)杀死进程 18)继续 19)暂停

(6)jobs

查看当前后台进程编号

(7)fg 后台进程编号

将一个后台进程调到前台

7.进程相关的函数

fork()

子进程:操作系统通过完整拷贝父进程0-3G的用户空间数据到子进程

内核空间拷贝部分内容:PCB块

PID不拷贝、PPID不拷贝

程序执行的位置、文件管理要拷贝

PCB块:进程控制块

注意:

(1)进程共用3G-4G这1G的内核空间

(2)但各自进程0-3G用户空间互相独立,不能互相通信

(3)进程间不能直接通信,通信需要借助内核空间(IPC机制)

#include <sys/types.h>

#include <unistd.h>

pid_t fork(void);

功能:创建新进程,新进程叫子进程,原来的进程为父进程

返回值:

成功:父进程中返回子进程的PID号;子进程中返回0

失败:-1,没有新进程被创建

getpid():获取当前进程自己的PID号

petppid():获取当前进程的父进程的PID号

示例:

复制代码
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

int main(void)
{
    pid_t pid = fork();
    printf("pid = %d\n",pid);

    if(pid > 0)
    {
        while(1)
        {
            printf("Father process:myid = %d, son id = %d\n",getpid(),pid);
            sleep(1);
        }
    }
    else if(pid == 0)
    {
        while(1)
        {
            printf("son process:myid = %d, father id = %d\n",getpid(),getppid());
            sleep(1);
        }
    }
    else
    {
        perror("fork error");
    }

    return 0;
}
相关推荐
Winner_hwx15 分钟前
华为ICT大赛备赛复习1
服务器·网络·华为
宗介波妞1 小时前
Wireshark 抓取 IEC104 报文:常见异常报文排查与标志位解读
服务器·网络·wireshark
网硕互联的小客服2 小时前
各个版本的Linux系统如何修改远程端口ssh端口?
linux·运维·服务器·网络
云泽8082 小时前
STM32 USART 详解(八):C I/O 串口重定向原理与实现
c语言·stm32·嵌入式硬件
ThornArmor2 小时前
重铸1996|肉体渲染:关节的裂缝:分段模型积木拼装与未成熟的 RSP 矩阵骨骼动画形变
c语言·汇编·c++·python·硬件架构·游戏机
T1mzhou2 小时前
ARM64 Linux 6.10 内核驱动(12):dd.c:probe/ remove、延迟 probe
linux·服务器·c语言·arm开发·arm
白色的北极熊4 小时前
c语言 scanf 输入流有空格,逗号 说明
c语言
Logic1014 小时前
C语言/数据结构位运算题解:异或XOR找出货船中的“独特载货量“——只出现一次的数字
c语言·数据结构·数组·位运算·时间复杂度·算法题·异或性质
yunwei376 小时前
eBPF 示例教程:实现 `scx_nest` 调度器
linux·后端·性能优化
朽棘不雕6 小时前
关于重定向的小补充
linux