Linux:进程的概念,进程相关函数

 一、进程的概念

1.进程

     进程是系统进行资源分配和调度的一个独立单元,它是操作系统结构的基础。进程是程序的一次执行过程,包含了程序代码、当前活动、系统资源(如CPU、内存、文件等)的使用情况等信息。每个进程都有自己独立的内存空间和系统资源。 

2.pcb  

  pcb 是 Process Control Block(进程控制块)的缩写,即进程控制块,是操作系统中用于存储进程管理所需信息的数据结构。它记录了操作系统的进程管理所需要的所有信息,包括:

  • PID(进程标识符):唯一标识一个进程。
  • 当前工作路径:进程当前的工作目录,通过chdir等系统调用可以改变。
  • umask:文件创建掩码,影响新创建文件的权限。例如,umask 0002意味着新创建的文件默认不允许组用户和其他用户写入。
  • 打开的文件列表:进程打开的所有文件及其相关信息,如文件描述符、文件模式等。
  • 信号相关设置:处理异步事件,如中断、错误等。进程可以定义对不同信号的处理方式(忽略、捕捉或默认处理)。
  • 用户ID和组ID:执行该进程的用户和组的身份标识。
  • 进程资源的上限:系统为该进程分配的资源上限,如最大打开文件数、最大内存使用量等。可以通过ulimit -a命令查看或设置这些限制。

3.进程和程序的区别

  1. 静态与动态
    • 程序:是静态的,它是一组指令和数据的集合,存储在非易失性存储介质(如硬盘)上。程序本身不执行任何操作,它只是等待被执行。
    • 进程:是动态的,它是程序在计算机上的一次执行过程。它包含了程序代码、数据以及系统分配给该程序的各种资源(如内存空间、文件描述符等)。进程是系统进行资源分配和调度的一个独立单元。
  2. 存在性与生命周期
    • 程序:是永存的,只要存储介质没有损坏,程序就可以一直存在。
    • 进程:是暂时的,有生命周期,包括创建、运行、等待、挂起、终止等状态。一旦进程执行完毕或被系统终止,它就不再存在。
  3. 状态变化
    • 程序:没有状态变化,它只是静态的代码和数据集合。
    • 进程:有状态变化,如运行状态、就绪状态、阻塞状态等。进程的状态会随着执行过程中的事件(如I/O操作、时间片结束等)而发生变化。
  4. 并发性
    • 程序:没有并发性,它只是一个代码和数据的集合,不会自己执行。
    • 进程:具有并发性,系统中可以同时运行多个进程,这些进程之间可能并发执行,也可能并行执行(在多处理器或多核处理器上)。
  5. 资源竞争
    • 程序:不直接涉及资源竞争,因为它不直接执行。
    • 进程:进程之间会存在资源竞争,因为它们可能同时需要访问CPU、内存、I/O设备等资源。操作系统通过调度算法来管理这些资源,确保进程的公平性和高效性。
  6. 与程序的关系
    • 一个程序可以多次运行,每次运行都会创建一个新的进程。因此,一个程序可以对应多个进程。
    • 一个进程可以执行一个或多个程序,特别是在现代操作系统中,一个进程可以加载并执行多个模块或库。
  7. 内存分布
    • 在许多操作系统中(如Linux),进程的地址空间被划分为用户空间和内核空间。用户空间通常位于低地址区域(如0-3G),用于存储进程的代码、数据等;内核空间位于高地址区域(如3G-4G),用于存储操作系统代码和数据,以及实现进程调度、内存管理等核心功能。这种划分是虚拟的,通过内存管理单元(MMU)和页表实现物理内存和虚拟内存之间的映射。

4.进程的分类

进程分类: 1、交互式进程

                   2、批处理进程 shell脚本

                   3、 守护进程

*5.进程的状态:

         3个状态,就绪→执行态→阻塞(等待,睡眠)基本操作系统
    

linux中的状态,运行态,睡眠态,僵尸,暂停态。

6.进程的作用

  1. 资源封装:进程封装了运行程序所需的资源,使得操作系统能够方便地对这些资源进行管理和调度。
  2. 执行程序:进程是程序执行的载体,操作系统通过创建进程来执行程序,实现程序的动态运行。
  3. 实现并发:操作系统通过创建多个进程,可以在同一时间段内执行多个任务,从而提高系统的整体效率和吞吐量。
  4. 系统安全:通过进程隔离,操作系统可以防止不同进程之间的相互干扰,保证系统的安全性和稳定性。

7.并发与并行的区别

  1. 定义
    • 并发:指两个或多个事件在同一时间间隔内发生,但这些事件并不是同时发生的。在操作系统中,并发通常指的是多个进程或线程在宏观上同时运行,但在微观上(即CPU的指令执行层面)是交替执行的。
    • 并行:指两个或多个事件在同一时刻同时发生。在并行计算中,多个任务可以同时被执行,因为它们被分配到不同的处理器或处理单元上。
  2. 资源需求
    • 并发通常不需要额外的硬件资源,它主要通过时间片轮转、上下文切换等机制来实现多个任务的交替执行。
    • 并行则需要额外的硬件资源来支持,如多核处理器、分布式计算环境等,以便能够同时执行多个任务。
  3. 效率与速度
    • 并发虽然可以在宏观上提高系统的整体效率,但在单个任务的执行速度上并没有明显的提升。
    • 并行则能够显著提高单个任务的执行速度,因为它允许多个任务同时执行,从而减少了总体执行时间。
while (1) {  
    发视频  
}  
  
while (1) {  
    上下左右  
}
  • 如果这两个任务在同一台计算机上执行,并且只有一个CPU核心可用,那么它们将通过并发的方式执行,即操作系统通过时间片轮转等方式使这两个任务交替执行。
  • 如果这台计算机有多个CPU核心,且这两个任务被分配到不同的CPU核心上执行,那么它们将并行执行,即同时执行。

需要注意的是,并发和并行是操作系统和硬件层面的概念,而上述代码示例并没有直接体现这些概念。在实际应用中,要实现并发或并行,通常需要使用多线程或多进程等编程技术

进程的调度

进程调度是操作系统内核的主要功能之一,它决定了哪个进程可以获得CPU资源并运行。进程调度的目标是公平、高效地分配CPU资源,以满足进程的运行需求。以下是进程调度的几个关键点:

  1. 调度算法
    • 轮转调度(Round-Robin, RR):将CPU时间分成若干个时间片,每个进程在一个时间片内执行,时间片结束后切换到下一个进程。这种算法可以提高CPU的利用率,但可能会导致上下文切换开销增加。
    • 先进先出(First-In, First-Out, FIFO):也称为先来先服务(FCFS),按照进程到达系统的先后顺序进行调度,先到达的进程先执行。这种算法简单直观,但可能会导致长作业等待时间过长。
    • 优先级调度:根据进程的优先级进行调度,优先级高的进程先执行。这种算法可以根据进程的重要性进行调度,但可能会导致低优先级进程饿死。
    • 短作业优先(Shortest Job First, SJF):选择执行时间最短的进程。这种算法可以提高系统的整体效率,但同样可能导致长作业饥饿。
    • 其他算法:如多级反馈队列调度、多级队列调度等,这些算法结合了上述算法的某些特点,以更好地适应不同的应用场景。
  2. 调度时机
    • 进程创建时:当新进程被创建时,需要被加入到调度队列中等待CPU资源。
    • 进程终止时:当进程执行完毕或异常终止时,需要释放其占用的CPU资源,并重新调度其他进程。
    • 进程阻塞时:当进程因等待某个事件(如I/O操作完成)而阻塞时,需要将其从CPU上撤下,并调度其他进程执行。
    • 进程唤醒时:当被阻塞的进程因等待的事件完成而被唤醒时,需要将其重新加入到调度队列中等待CPU资源。
  3. 调度过程
    • 收集系统信息:操作系统需要收集有关系统中所有进程的信息,如进程的状态、优先级、需要的资源等。
    • 选择进程:根据调度算法和调度策略选择下一个要执行的进程。
    • 分配CPU:将选中的进程分配到CPU上,并将其状态设置为运行状态。
    • 执行进程:进程在CPU上执行其指令和数据。
    • 回收CPU:当进程执行完毕或需要被替换时,回收其占用的CPU资源。

进程上下文切换

进程上下文切换是操作系统内核在CPU上对于进程(包括线程)进行的一种活动,主要目的是在多个进程之间共享CPU资源。以下是进程上下文切换的几个关键点:

  1. 概念
    • 上下文切换可以认为是内核在CPU上对于进程进行的活动,包括挂起一个进程、存储其上下文信息、检索下一个进程的上下文信息、恢复其在CPU上的执行状态,并跳转到程序计数器所指向的位置以继续执行。
  2. 发生时机
    • 中断发生时:当发生中断(如硬件中断、软件中断)时,CPU会暂停当前执行的进程,并保存其上下文信息,然后跳转到中断处理程序执行。当中断处理完成后,CPU会恢复之前被挂起的进程的上下文信息,并继续执行。
    • 进程调度时:当需要进行进程调度时(如时间片用完、进程阻塞/唤醒等),操作系统内核会保存当前执行进程的上下文信息,并检索下一个要执行的进程的上下文信息,然后恢复其在CPU上的执行状态。
  3. 上下文信息
    • 上下文信息是指进程在被调度执行前的状态信息,包括程序计数器(PC)、栈指针、寄存器的值等。这些信息用于恢复进程的执行状态,以便进程可以从上次暂停的地方继续执行。上下文信息通常存储在PCB(进程控制块)中,以便操作系统可以快速获取和更新这些信息。
  4. 性能影响
    • 上下文切换是操作系统内核中的一项重要活动,但它也会带来一定的性能开销。频繁的上下文切换会增加CPU的负载和延迟,降低系统的整体性能。因此,在设计操作系统和应用程序时,需要合理控制上下文切换的频率和开销。
内核的其他主要功能

除了进程调度和进程上下文切换外,操作系统的内核还负责以下主要功能:

  • 硬件管理:管理计算机的硬件资源,如CPU、内存、I/O设备等。
  • BIOS接口:提供与BIOS(基本输入输出系统)的接口,以便操作系统能够访问计算机的底层硬件。
  • I/O管理:处理输入/输出操作,包括与外设的通信和数据传输。
  • 文件系统:管理磁盘上的文件和目录结构,提供文件的创建、读取、写入、删除等操作。
  • 驱动管理:管理各种设备驱动程序,

二、查询进程相关命令

*1.ps aux

    查看进程相关信息

        1.就绪态、运行态    R
        2.睡眠态、等待态    
            可唤醒等待态    S
            不可唤醒等待态    D
        3.停止态    T
        4.僵尸态    Z
        5.结束态    

  2.top

根据CPU占用率查看进程相关信息

 3.kill和killall发送一个信号

    kill -2 PID  15
    发送信号+PID对应的进程,默认接收者关闭

  
    killall -9 进程名
    发送信号 进程名对应的所有进程
    killall a.out

*4.fork();

   pid_t fork(); (叉子)
    一次调用,会返回两次。不需要传参数
    子进程先运行和是父进程先进程,顺序不确定。
    变量不共享。
    子进程复制父进程的0到3g空间和父进程内核中的PCB,但id号不同。
    功能:通过该函数可以从当前进程中克隆一个同名新进程。
          克隆的进程称为子进程,原有的进程称为 父进程。
          子进程是父进程的完全拷贝。
          子进程的执行过程是从fork函数之后执行。
          
          子进程与父进程具有相同的代码逻辑。

    返回值:int 类型的数字。
            在父进程中:成功 返回值是子进程的pid号 >0
                        失败 返回-1;
            在子进程中:成功 返回值 0
                        失败 无

练习:让2个while同时进行

#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
int main(int argc, const char *argv[])
{
	pid_t ret=fork();
	if(ret>0)
	{
		while(1)
		{
			printf("aaa\n");
			sleep(1);
		}
	}
	else if(ret==0)
	{
		while(1)
		{
			printf("ccc\n");
			sleep(1);
		}
	}
	else 
	{
		perror("fork error\n");
		return 1;
	}
	
	return 0;
}

运行结果会出现   aaa  aaa  是因为:进程是随机的。

5.getpid

pid_t getpid(void);
    功能:
        获得调用该函数进程的pid
    参数:
        缺省
    返回值:
        进程的pid

       
   6.getppid

  pid_t getppid(void);
    功能:
        获得调用该函数进程的父进程pid号
    参数:
        缺省
    返回值:
        返回父进程id号
练习:

fork()&&fork()||fork()

几个进程?  五个  看最后一层有多少个进程

分析:fork()它返回值有两种情况,大于0,等于0,&&如果左边为1,右边执行,如果为0,右边不执行,|| 如果左边为1,右边不执行,如果左边为0,右边执行,按照这个思想去分析。

练习:动态生成n个子进程,并打印输出各自进程的pid号。

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
    
    int n =5;
    int i = 0 ;
    for(i=0;i<n;i++)
    {
    
        pid_t pid = fork();
        if(pid>0)
        {
            
        }
        else if(0 == pid)
        {
            printf("child pid:%d\n",getpid());
            exit(0);
        }
        else 
        {
            perror("fork");
            return 1;
        }
    }
    return 0;
}

  • 7
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值