【Linux】初识系统调用进程状态

news2024/11/29 12:36:03

文章目录

  • 1. 什么是系统调用
    • 1.1 通过系统调用获取进程标示符
    • 通过其他方式查看PID
      • Top
      • PS
      • 使用PID
    • 1.2 通过系统调用创建进程-fork初识
  • 2. 进程状态
    • 看看Linux内核源代码怎么定义
    • 查看状态
    • Z(zombie)-僵尸进程
    • 僵尸进程危害
  • 孤儿进程


在这里插入图片描述

1. 什么是系统调用

在linux中,系统调用是指操作系统提供给用户程序调用的一组特殊接口,用户程序可以根据这组接口获得操作系统内核的服务;系统调用规定了用户进程陷入内核的具体位置,或者说规划了用户访问内核的路径,只能从固定位置进入内核。

通俗点讲:在开发角度,操作系统对外会表现为一个整体,但是会暴露自己的部分接口,供上层开发使用,这部分
由操作系统提供的接口,叫做系统调用

image-20221119202338323

系统调用类比于银行存钱,到银行存钱对于老百姓来说,是不可以直接跑到银行内部进行操作的,因为银行是有责任保护银行中的一切数据和钱财,所以银行一般都要封闭起来管理,但是又不能完全封闭,因为老百姓也要来办理业务,所以银行最终呈现半封闭的状态,在前台有一小半个小窗口是对老百姓开放的,以方便大家办理业务。

同理操作系统也是如此,我们不能直接对系统做操作,只能通过系统调用来进行访问。


1.1 通过系统调用获取进程标示符

进程id (PID)

首先我们来学习PID这个概念,PID全称Process ID,是标识和区分进程的ID。Linux系统保证不会同时存在两个进程拥有相同的PID,但在一个进程结束之后,其PID可能会再次被分配给新进程

父进程id(PPID)

每个进程除了一定有PID还会有PPID,也就是父进程ID,通过PPID可以找到父进程的信息。

为什么进程都会有父进程ID呢?因为进程都是由父进程衍生出来的

操作系统给我们提供了两个查看pid和ppid的系统接口

//所需的头文件
#include <sys/types.h>
#include <unistd.h>
//函数接口
pid_t getpid(void);//查看进程ID
pid_t getppid(void);//查看父进程ID

image-20221119204400248

运行结果:

image-20221119205305859


通过其他方式查看PID

首先我们想知道进程的PID,可以通过top或者ps命令来查看。

Top

在命令行执行top后,得到类似下面的输出

image-20221119205436415

PS

执行ps axj后输出如下,其中axj参数让ps命令显示更详细的参数信息。

image-20221119205532818

使用PID

拿到PID后,我们就可以通过kill命令来结束进程了,也可以通过kill -9或其他数字向进程发送不同的信号。

信号是个很重要的概念,我们后面会详细介绍,那么有了进程ID,我们也可以看看进程名字。


1.2 通过系统调用创建进程-fork初识

  • 运行 man fork 认识fork
  • 感性的知道fork有两个返回值
  • 父子进程代码共享,数据各自开辟空间,私有一份(采用写时拷贝)(后面章节细讲)
//头文件
#include <unistd.h>
pid_t fork(void);

image-20221119210139804

从它的介绍中可以知道fork对父进程返回大于0的数字(本质上是子进程的pid),对子进程返回0,失败返回-1

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
    int ret = fork();
    if(ret < 0)
    {
        perror("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);
    }
    sleep(1);
    return 0;
}
image-20221119211321507

image-20221119211338326


2. 进程状态

看看Linux内核源代码怎么定义

根据进程的定义,我们知道进程是代码运行的实体,而进程有可能是正在运行的,也可能是已经停止的,这就是进程的状态。

网上有人总结进程一共5种状态,也有总结是8种,究竟应该怎么算呢,最好的方法还是看Linux源码。

下面的状态在kernel源代码里定义:

/*
* 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 */
};

这真的是Linux的源码,可以看出进程一共7种状态,含义也比较清晰,注意其中D(disk sleep)称为不可中断睡眠状态(uninterruptible sleep)。

  • R运行状态(running) : 并不意味着进程一定在运行中,它表明进程要么是在运行中要么在运行队列
    里。
  • S睡眠状态(sleeping): 意味着进程在等待事件完成(这里的睡眠有时候也叫做可中断睡眠
    (interruptible sleep))。
  • D磁盘休眠状态(Disk sleep)有时候也叫不可中断睡眠状态(uninterruptible sleep),在这个状态的
    进程通常会等待IO的结束。
  • T停止状态(stopped): 可以通过发送 SIGSTOP 信号给进程来停止(T)进程。这个被暂停的进程可
    以通过发送 SIGCONT 信号让进程继续运行。
  • X死亡状态(dead):这个状态只是一个返回状态,你不会在任务列表里看到这个状态

查看状态

通过ps aux可以看到进程的状态。

O:进程正在处理器运行,这个状态从来没有见过.
S:休眠状态(sleeping)
R:等待运行(runable)R Running or runnable (on run queue) 进程处于运行或就绪状态
I:空闲状态(idle)
Z:僵尸状态(zombie)
T:T停止状态(stopped)
D: 不可中断的深度睡眠,一般由IO引起,同步IO在做读或写操作时,cpu不能做其它事情,只能等待,这时进程处于这种状态,如果程序采用异步IO,这种状态应该就很少见到了

其中就绪状态表示进程已经分配到除CPU以外的资源,等CPU调度它时就可以马上执行了。运行状态就是正在运行了,获得包括CPU在内的所有资源。等待状态表示因等待某个事件而没有被执行,这时候不耗CPU时间,而这个时间有可能是等待IO、申请不到足够的缓冲区或者在等待信号。


Z(zombie)-僵尸进程

僵死状态(Zombies)是一个比较特殊的状态。当进程退出并且父进程(使用wait()系统调用,后面讲)
没有读取到子进程退出的返回代码时就会产生僵死(尸)进程
僵死进程会以终止状态保持在进程表中,并且会一直在等待父进程读取退出状态代码。
所以,只要子进程退出,父进程还在运行,但父进程没有读取子进程状态,子进程进入Z状态

一个创建维持30秒的僵死进程例子 :

#include <stdio.h>
#include <stdlib.h>
int main()
{
	pid_t id = fork();
	if (id < 0){
		perror("fork");
		return 1;
	}
	else if (id > 0){ //parent
		printf("parent[%d] is sleeping...\n", getpid());
		sleep(30);
	}
	else{
		printf("child[%d] is begin Z...\n", getpid());
		sleep(5);
		exit(EXIT_SUCCESS);
	}
	return 0;
}

编译并在另一个终端下启动监控

image-20221119213127851

开始测试

image-20221119213148845

看到结果

image-20221119213231748


僵尸进程危害

  • 进程的退出状态必须被维持下去,因为他要告诉关心它的进程(父进程),你交给我的任务,我办的怎
    么样了。可父进程如果一直不读取,那子进程就一直处于Z状态?是的!
  • 维护退出状态本身就是要用数据维护,也属于进程基本信息,所以保存在task_struct(PCB)中,换句话
    说, Z状态一直不退出, PCB一直都要维护?是的!
  • 那一个父进程创建了很多子进程,就是不回收,是不是就会造成内存资源的浪费?是的!因为数据结构
    对象本身就要占用内存,想想C中定义一个结构体变量(对象),是要在内存的某个位置进行开辟空
    间!
  • 内存泄漏?是的!
  • 如何避免?后面详细学习

孤儿进程

父进程如果提前退出,那么子进程后退出,进入Z之后,那该如何处理呢?

父进程先退出,子进程就称之为“孤儿进程”

孤儿进程被1号init进程领养,当然要有init进程回。

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
	pid_t id = fork();
	if (id < 0){
		perror("fork");
		return 1;
	}
	else if (id == 0){//child
		printf("I am child, pid : %d\n", getpid());
		sleep(10);
	}
	else{//parent
		printf("I am parent, pid: %d\n", getpid());
		sleep(3);
		exit(0);
	}
	return 0;
}

image-20221119213724216

image-20221119213758194

可以看到父进程退出了,子进程的ppid已经变成了1号进程,此时就是操作系统。


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/26486.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[附源码]java毕业设计校园志愿者服务管理系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

Node_exporter主机探针部署

部署需求分析 使用ansible批量部署node-exporter监控客户端 node-exporter解压安装目录为home 添加至Linux服务重新加载&#xff0c;启动模块并设置开机启动 测试环境&#xff08;centos 7——3.10.0-1160.el7.x86_64&#xff09;运行成功 因为部署步骤较少&#xff0c;单个pla…

主从延迟读写不一致解决方案分析

具体业务场景方案分析 问题背景&#xff1a; 虽然强制走写库&#xff0c;避免了主从延迟带来的读库数据不一致问题&#xff0c;但是增加了写库的QPS&#xff0c;带来了巨大压力&#xff0c;所以通过限流来保护db&#xff0c;但这样会降低QPS。 业务上暂时不清楚&#xff0c;所…

[附源码]java毕业设计校园新闻管理系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

转铁蛋白修饰脂质体定制,Transferrin-Liposome

人转铁蛋白&#xff08;Human Transferrin&#xff09;主要在肝脏合成&#xff0c;是由位于同源N-端和C-端的两个叶片&#xff08;Lobe&#xff09;组成的一种单链糖蛋白。人转铁蛋白共含678个氨基酸残基&#xff0c;等电点为5.9、分子量为76kD。每分子的转铁蛋白能携带2个三价…

Mybatsi从入门到精通、从精通到卸载,这一篇就足够了【中篇】

资料下载 链接: https://pan.baidu.com/s/1i_D3hSkMElUyxBC0OJqRRg?pwdthg4提取码: thg4 简介 MyBatis 是一款优秀的持久层框架&#xff0c;它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简…

深度学习入门(四十七)计算机视觉——SSD和YOLO简介

深度学习入门&#xff08;四十七&#xff09;计算机视觉——SSD和YOLO简介前言计算机视觉——SSD和YOLO简介课件&#xff08;单发多框检测SSD&#xff09;生成锚框SSD模型效果总结课件&#xff08;YOLO&#xff09;YOLO&#xff08;你只看一次&#xff09;效果前言 核心内容来…

nvm的下载,安装与使用详解

一、安装nodejs方式有很多种 第一种&#xff1a;官网下载  通过nodejs官网下载安装 &#xff0c;但有个缺陷&#xff0c;不同版本的nodejs无法顺利的切换。 第二种: NVM安装  NVM可以帮助我们快速切换 node版本。 二、 下载nvm安装包 官方下载地址&#xff1a;http://​ h…

力扣(LeetCode)41. 缺失的第一个正数(C++)

类计数排序 小于 111 &#xff0c;大于 nnn 的数&#xff0c;不会对答案造成影响。所以只要考虑 1——n1——n1——n 的数。 由于题目要求 O(1)O(1)O(1) 空间&#xff0c;参考计数排序思想&#xff0c;利用原数组 numsnumsnums 存储 1——n1——n1——n &#xff0c;需要将 1…

网易有道三季报解读:转型“有道”,但依旧道阻且长

11月17日晚间&#xff0c;美股上市公司网易有道&#xff08;以下简称“有道”&#xff09;发布2022年第三季度财报&#xff0c;营收同比大幅增长&#xff0c;亏损大幅收窄&#xff0c;成绩喜人。有道去年三季度自7月24日“双减”政策出台后被迫开始转型&#xff0c;整整一年过去…

MySQL-Day02 数据库以及数据表的基本操作

目录 一、数据库的基本操作 1.1 创建数据库 1.2 删除数据库 1.3 使用创建的数据库 1.4 扩展知识&#xff1a;InnoDB表 面试题&#xff1a;InnoDB和MyISAM的区别&#xff1f; 二、数据表的基本操作 2.1 创建数据表 MySQL数据类型 2.2 表约束 2.2.1 主键约束 2.2.2 非…

求求了!这份GitHub 70K+的纯手写RabbitMQ 笔记都给我码住好吗!

说到消息中间件&#xff0c;大部分人的第一印象可能是Kafka。毕竟Kafka自问世以来&#xff0c;就顶着高并发&#xff0c;大流量的光环。当然了Kafka也不负众望&#xff0c;在大数据处理方面一直独领风骚。 这里想说说另一款同样优秀的消息中间件RabbitMQ。 选RabbitMQ还是Kaf…

一种多源信息融合方法及其应用(Matlab代码实现)

&#x1f352;&#x1f352;&#x1f352;欢迎关注&#x1f308;&#x1f308;&#x1f308; &#x1f4dd;个人主页&#xff1a;我爱Matlab &#x1f44d;点赞➕评论➕收藏 养成习惯&#xff08;一键三连&#xff09;&#x1f33b;&#x1f33b;&#x1f33b; &#x1f34c;希…

基于armv8的kvm实现分析(三)kvm初始化流程

本文基于以下软硬件假定&#xff1a; 架构&#xff1a;AARCH64 内核版本&#xff1a;5.14.0-rc5 1 kvm概述 kvm是基于linux内核实现的一种type 2虚拟化方案&#xff0c;它作为内核的一个模块负责虚拟化环境初始化&#xff0c;虚拟机和虚拟cpu模拟&#xff0c;以及IO捕获与转…

发布适用于 .NET 7 的 .NET MAUI

我们在六个月前向您介绍了 .NET 多平台应用程序 UI (MAUI)&#xff0c;现在我们很高兴地宣布 .NET MAUI 在我们的下一个主要版本 .NET 7 中普遍可用。在此短的时间范围内&#xff0c;我们在 .NET MAUI 中的主要工作是解决您的主要反馈报告、改进 CollectionView 的性能&#xf…

P8842 [传智杯 #4 初赛] 小卡与质数2 垃圾筛

题目&#xff1a; 思路&#xff1a; 首先排除比较每一个比X小的数去看结果&#xff0c;因为一定会tle 然后考虑去和每一个比X小的数去看结果&#xff0c;去判定是否比它小&#xff0c;看起来是优秀了一些&#xff0c;但是 n以内的质数比例大约是1ln(n)\frac{1}{ln(n)}ln(n)1​…

MCE | 线粒体和能量代谢的关系

线粒体是细胞生命活动的能量工厂&#xff0c;是几乎所有真核生物都存在的一种细胞器。它的主要功能是进行氧化磷酸化 (OXPHOS) 合成 ATP&#xff0c;是糖类、脂肪和氨基酸等物质的最终氧化释放能量的场所。自带“内核”和“核心技术”的线粒体&#xff1a;线粒体内有一套独立的…

JAVA中使用最广泛的本地缓存?Ehcache的自信从何而来3 —— 解析Ehcache的各种集群方案,本地缓存如何变身分布式缓存

大家好&#xff0c;又见面了。 上一篇文章中&#xff0c;我们知晓了如何在项目中通过不同的方式来集成Ehcache并在业务逻辑中进行使用。作为JAVA本地缓存框架综合实力天花板级别的Ehcache&#xff0c;除了在本地缓存方面具有强悍的实力外&#xff0c;还具有一个其它对手所不具…

Metabase学习教程:提问-6

搜索表格和问题 了解如何使用筛选器和自定义表达式在SQL查询和简单问题中进行搜索。在表格中查找单词或短语现在比以往任何时候都容易。 添加过滤器给你的问题可以让你的问题搜索文本轻而易举。您可以使用示例数据库包含在每个Metabase安装中。 在问题中搜索 我们将从单击浏…

linux笔记(8):东山哪吒D1H移植lvgl(HDMI输出)

文章目录1. 下载&#xff0c;修改&#xff0c;编译源码1.1下载源码1.1.1新建一个lvgl目录&#xff0c;在该目录下下载源码1.1.2 在lvgl目录下再建一个myspace/lvgl_demo目录&#xff0c;把参与编译的文件拷贝到本目录1.2 修改源码1.3编译源码2.拷贝到东山哪吒开发板运行3.已移植…