• [Linux] 进程入门


    在这里插入图片描述


    📄前言

    作为一名程序员,我们天天都在与代码打交道,但你是否有了解过我们的程序是如何在操作系统中运行与调度的呢?如果你对进程与计算机不甚了解,那么本文将带领你走向操作系统进程的第一步。

    计算机的结构体系与概念

    在了解进程的相关知识前,我们需要先了解以下计算机的组成体系及其概念。

    冯诺依曼体系结构

    冯诺依曼体系结构是一种计算机的组成方案,因为使用其体系构造的计算机性价比很高,所以我们日常生活中使用的计算机,如笔记本、服务器等大部分都遵守着冯诺依曼体系结构。

    冯诺依曼体系结构规定了计算机由五个部分组成,控制器、运算器、储存器、输入设备、输出设备。

    在这里插入图片描述
    注意:

    • 这里的储存器指的是内存
    • 不考虑缓存情况,这里的CPU能且只能对内存进行读写,不能访问外设(输入或输出设备)
    • 外设(输入或射出设备)要输入或输出数据,只能写入内存或从内存中读取
    • 总的来说,所有设备都只能直接和内存打交道

    操作系统

    概念

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

    • 内核(进程管理、内存管理、文件管理、驱动管理)
    • 其他程序(函数库、shell程序等)

    目的与定位

    操作系统是纯正用于管理的软件,操作系统与硬件交互,管理所有的软硬件资源。

    在这里插入图片描述

    进程

    概念

    如果你没有学习过系统知识,可能会以为进程就是把二进制程序拷贝执行而已,但其实进程指的是PCB(process control block)+ 可执行程序

    描述进程-PCB

    PCB又名进程控制块,这是一个进程属性的集合体,用于描述进程,在linux内核是一种链式结构(task_struct),它会被装载到内存中。

    task_struct

    在Linux里面描述进程的结构体就叫做task_struct,其内容分为:

    • 标志符:描述本进程的唯一标识符,用于区别其他进程 。
    • 状态:任务装提、退出代码、退出信号等 。
    • 优先级:相对于其他进程的优先级。
    • 程序计数器:程序中即将被执行的下一条指令的地址。
    • 内存指针:包括程序代码和进程相关数据的指针,还有和其他进程共享的内存块的指针。
    • 上下文数据:进程执行时处理器的寄存器中的数据「Ip指针」
    • I / O状态信息:包括显示的I / O 请求,分配给进程的 I / O设备和被进程使用的文件列表。
    • 记账信息:可能包括处理器总和,使用的时钟数总和,时间限制,记帐号等。
    • 其他信息。

    检查进程

    进程的信息可以通过linux目录中的/proc文件夹来查看
    在这里插入图片描述
    或者你也可以用top / ps 等指令工具来获取

    利用fork创建子进程

    在Linux平台下,C语言可以用fork函数来创建子进程,父子进程代码共享,当数据使用写实拷贝,当数据没被修改时,数据共用。

    #include 
    #include 
    #include 
    
    int main() {
    	//fork如果创建子进程成功则返回0,失败返回-1。
    	pid_t id = fork();	
    	if(id == 0)
    	{
    		printf("我是子进程\n");
    	}
    	else
    	{
    		printf("我是父进程\n");
    	}
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    进程状态

    在Linux中进程拥有多种状态,一个进程可以有多个状态。让我们来看看Linux内核里面对进程状态的定义吧。

    /*
    * 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 */
    "X (dead)", /* 16 */
    "Z (zombie)", /* 32 */
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • R 运行状态:说明进程要么在运行,要么在运行队列里。
    • S 睡眠状态:说明进程在等待事件完成。
    • D 磁盘休眠状态:又名不可中断睡眠状态(uninterruptible sleep),在这个状态的进程通常会等待IO的结束。
    • T 停止状态:通过发送 SIGSTOP 信号来给进程停止,这个被停止的进程可以通过发送 SIGCONT 信号让进程继续运行。
    • X 死亡状态:这个状态只是一个返回状态,你不会在任务列表看到这个状态。

    进程状态查看

    我们可以通过top指令或ps指令来检查进程
    在这里插入图片描述

    僵尸进程

    僵尸进程是一种比较特殊的状态,当子进程退出,而父进程没有读取到子进程的返回码时就会产生僵尸进程。因为僵尸进程还没被系统清理其开辟的空间,所以僵尸进程还会导致内存泄漏。

    C语言创建僵尸进程:

    #include 
    #include 
    
    int main()
    {
    	pid_t id = fork();
    	if(!id)
    	{	//C语言可以通过getpid指令来获取进程的id
    		printf("child[%d] is return....\n", getpid());
    		sleep(2);
    		exit(EXIT_SUCCESS);
    	}
    	else 
    	{
    		printf("parent[%d] is sleeping...\n",getpid());
    		sleep(10);
    	}
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    在这里插入图片描述

    孤儿进程

    孤儿进程和僵尸进程恰好相反,如果父进程先退出,子进程继续运行,那么子进程就会成为孤儿进程。成为孤儿进程后,就被交给pid为1的进程管理,也就是系统。

    来段代码:
    进程优先级
    基本概念
    cpu资源分配的先后顺序,就是指进程的优先权(priority)。
    优先权高的进程有优先执行权利。配置进程优先权对多任务环境的linux很有用,可以改善系统性能。
    还可以把进程运行到指定的CPU上,这样一来,把不重要的进程安排到某个CPU,可以大大改善系统整
    体性能。
    查看系统进程
    在linux或者unix系统中,用ps –l命令则会类似输出以下几个内容:
    #include 
    #include 
    #include 
    
    int main()
    {
    	pid_t id = fork();
    	int i = 0;
    	if (id == 0)
    	{	//child
    		while(i++ < 10)
    		{
    			printf("[%d] : child_pid[%d] : parent_pid[%d]\n", getpid(), getppid());
    			sleep(1);
    		}	
    	}
    	else
    	{	//parent
    		printf("parent[%d], is exit\n", getpid());
    		exit(0);
    	}
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    在这里插入图片描述

    📓总结

    📜博客主页:主页
    📫我的专栏:C++
    📱我的github:github

  • 相关阅读:
    洛谷-Directed Roads-(基环树总结)
    Python---函数的应用案例(多个)
    NPOI设定单元格格式(数值型插入)
    Git(四)底层命令:git对象、树对象、提交对象
    win7电脑一直闪屏是什么原因?
    什么是Integer128陷阱
    面向6G承载网的路由优化算法研究
    【机器学习】sklearn特征选择(feature selection)
    MySQL高级-读写分离-分库分表
    leetcode每天5题-Day01
  • 原文地址:https://blog.csdn.net/CaTianRi/article/details/134439965