Linux进程----概念

本文深入讲解了冯诺依曼体系结构下的操作系统原理,探讨了操作系统内核如何通过进程管理、内存管理、文件管理和驱动管理来调度系统资源。重点介绍了进程的概念、进程控制块(PCB)的结构和内容,以及Linux操作系统下的task_struct数据结构。此外,还讲解了系统调用、库函数的作用和区别,以及如何通过fork系统调用创建进程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

一、冯诺依曼体系结构

在这里插入图片描述

二、操作系统(Operator System)

(一)任何计算机系统都包含一个基本的程序集合,称为操作系统(OS)

  1. 内核(进程管理,内存管理,文件管理,驱动管理)
  2. 其他程序(例如函数库,shell程序等等)
  3. 操作系统的定位是:管理软硬件资源的软件
    eg:用struct结构体描述被管理对象,用链表或其他高效的数据结构组织被管理对象

(二)系统调用库函数

  1. 在开发角度,操作系统对外会表现为一个整体,但会暴露自身部分接口,供上层开发使用,这部分由操作系统提供的接口,叫做系统调用。
  2. 系统调用在使用上,功能比较基础,对用户的要求相对较高,所以,开发者对部分系统调用进行适度封装,从而形成库,更有利于更上层用户或者开发者进行二次开发。

进程

程序只是一个静态的文本文件,而进程是程序运行起来的一个实体
客观概念:程序的一个执行实例,正在执行的程序;
内核观点:担当分配系统资源(CPU时间,内存)的实体。

一、描述进程 -PCB
  1. 进程信息被放在一个叫做进程控制块的数据结构中,可以理解为进程属性的集合,称之为PCB(process control block),Linux操作系统下的PCB是:task_struct
  2. task_struct -PCB(进程控制块)之一:
    ①在Linux中描述进程的结构体叫做task_struct。
    task_struct是Linux内核的一种数据结构,它被装载到RAM(内存)里并且包含着进程的信息。
  3. task_ struct内容分类:
    标示符[pid]:描述本进程的唯一标示符,用来区别其他进程。
    ②状态:就绪状态,阻塞状态,运行状态。
    ③优先级:相对于其他进程的优先级。
    程序计数器:保存程序中即将被执行的下一条指令的地址。
    ⑤内存指针:包括程序代码,进程相关数据的指针,以及其他进程共享的内存块的指针。
    上下文数据:保存进程执行时处理器的寄存器中的数据。
    I/O状态信息:包括显示的I/O请求,分配给进程的I/O设备和被进程使用的文件列表。
    ⑧记账信息:
    a. CPU密集型程序:CPU计算的时间占多;
    b. IO密集型程序:和磁盘交互,进行IO占多;
    c. 并行:同一时间,多进程占用多CPU计算;
    d. 并发:多进程占用少CPU计算,每个进程运算一段时间要让出CPU供其他进程运算;
    e. 抢占式执行
  4. 组织进程:可在内核源代码里查询。所有运行在系统里的进程都以task_struct链表的形式存在内核里。
二、通过系统调用创建进程-fork初识
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main() {                                  //fork :
	int ret = fork();                         //1)在父进程中,fork返回新创建子进程的进程ID;
	if (ret < 0) {                            //2)在子进程中,fork返回0;
		perror("fork");                       //3)如果出现错误,fork返回一个负值。
		return 1;
	}
	else if (ret == 0) {           //child      
		printf("I am child: %d, ret: %d\n", getpid(), ret);
	}
	else {                         //father      
		printf("I am father: %d, ret: %d\n", getpid(), ret);
	}
	return 0;
}
三、查看进程状态
ps -l                    列出与本次登录有关的进程信息;
ps -aux                  查询内存中进程信息;
ps aux | grep (进程名)    查询(进程名)进程的详细信息;
top                      查看内存中进程的动态信息;
kill -9 pid              杀死标识符为pid的进程。
  1. R运行状态:并非进程一定在运行中,表明进程在运行中或是在运行队列。
    ./[可执行程序]& 将进程变为后台进程;
    fg 将进程变为前台进程。
  2. S睡眠状态(可中断睡眠):意味着进程在等待事件完成。
  3. D磁盘休眠状态(不可中断睡眠):此时进程通常会等待IO的结束。
  4. T停止状态:可以通过发送 SIGSTOP 信号给进程来停止(T)进程,让进程继续运行。
  5. X死亡状态:只是一个返回状态,任务列表没有这个状态。
  6. t 跟踪状态:调试的时候产生。
四、僵尸进程
  1. Z僵死状态:当进程退出并且父进程没有读取到子进程退出的返回代码时就会产生僵死(尸)进程,子进程以终止状态保持在进程表中,并且会一直在等待父进程读取退出状态代码。维护退出状态也属于进程基本信息,因为数据结构对象本身就要占用内存,所以保存在task_struct -PCB中,就会造成内存资源浪费。
  2. 如何处理僵尸进程?
    ①将僵尸进程的父进程杀掉,那僵尸进程就会变为孤儿进程,也就是会被1号进程将进程的返回状态回收掉,同时释放掉当前孤儿进程的PCB。
五、孤儿进程

父进程如果提前退出,子进程就称为孤儿进程,孤儿进程被1(Init)号进程领养,也就是会被1(Init)号进程将进程的返回状态回收掉。Init进程本身会创建很多进程,所以其本身创建的进程不能称为孤儿进程。

#include <stdio.h>                          
#include <unistd.h>                        
int main() {                
	pid_t pid = fork();  //创建子进程;系统调用函数fork(代码共享,数据独有)
    if(pid < 0) {   
		perror("fork erro");  //创建PCB是需要耗费内存的,没有内存的时候,可能会导致此结果
        return 0;
    }
    else if(pid == 0)
		printf("i am child:[%d]-[%d]\n", getpid(), getppid());  //子进程
    else    
		printf("i am father:[%d]-[%d]\n", getpid(), getppid());  //父进程
		//获取当前进程的pid,我们要使用getpid
		//获取当前进程的父进程的pid, 我们需要使用getppid
    return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值