Linux——进程初识(二)

news2024/12/27 10:10:51

1. 对当前目录创建文件的理解

我们知道在创建一个文件时,它会被默认创建到当前目录下,那么它是如何知道当前目录的呢?

对于下面这样一段代码

#include <stdio.h>
#include <unistd.h>

int main()
{
    fopen("tmp.txt", "w");
    while (1)
    {
        printf("这是一个进程\n");
        sleep(1);
    }

    return 0;
}

在它被加载成为一个进程时,我们查看相应的PID有

在Linux中所有进程是被存放在一个/proc目录中的,即

我们找到对应的PID就能进入并查看该进程,进入后发现

可以看到,在进程中有一个cwd文件,即current work dir(当前工作目录),在代码中使用fopen向磁盘中写入文件tmp.txt时,会自动的将cwd中的路径拼接到它的前面

2. 进程标识符

①PID

PID是进程标识符(Process Identifier)的缩写,它是一个唯一标识符,用于标识正在运行的每个进程。每个进程在系统中都有一个唯一的PID,可以通过PID来识别和管理进程。PID是一个非负整数,通常在系统启动时自动分配给进程,并且在一个给定的时间内是唯一的。

以以下代码为例

编译后运行有

有了标识符之后我们可以通过使用对应进程的PID使用kill命令来干掉该进程,即

kill -9 12489

那么我们如何知道当前进程的PID呢?

首先我们要知道PID是存放在task_struct中的,在我们使用ps命令时,它的本质就是遍历一遍task_struct链表,那么我们怎么获取呢——Linux肯定是不希望我们直接通过使用域访问符.来取得PID的,因此它提供了一个系统调用的接口即函数getpid(),它的手册如下

我们多运行几次后可以发现

对PID来说,PID只会保证当前运行期间有效,所以在不同的运行期间,其会不断变化

②PPID

PPID指的是父进程的PID,即父进程的进程ID号。与PID类似,要获取PPID我们也可以使用对应函数getppid(),其手册如下

在上面的多次运行中我们可以发现在不同运行期间PPID一般不变,我们查看可以发现

PID为6116的只有一个——bash,我们之前提到过,对于输入的命令,系统会单独创建一个bash来处理输入的命令,这样就能做到在输入命令时,会将其作为bash的子进程运行。而在断开主机重连后可以看到

此时PPID发生了变化,这是因为在登录到主机时,系统会单独新创建一个bash。

3. 创建进程——fork

我们以下面的代码为例

对其编译运行后我们可以使用

while :; do ps ajx | head -1 ; ps ajx | grep mycode | grep -v grep;sleep 1;done

来不断查看与mycode相关进程的状态

我们查看fork手册有

可以看到在手册中提到fork会返回两个值,返回id==0时,标识其为子进程,id>0时,标识其为父进程,而在运行结果中我们可以看到,父进程就是当前进程,子进程是新分支。至此,我们对于创建一个新进程有两种方法,其中一个就是使用./文件的方式在指令层面创建一个进程,另外一个就是使用fork函数在代码层面创建一个进程。其实在调用fork函数之后,会产生两个执行流。

在这里我们可以提出几个问题:

1. 为什么fork要给子进程返回0, 给父进程返回PID?

首先我们要知道,fork返回不同的值是为了让不同的执行流去执行不同的代码块,因为fork之后的代码是父子进程共享的,因此控制if等条件即可控制不同执行流。给子进程返回0只是一个标记,标志着子进程创建成功,而给父进程返回PID是因为对于一个父进程,其可能会有多个子进程,拿到子进程PID是为了标识唯一性。

2. fork函数是如何做到返回两次的?

首先我们要知道,创建一个子进程对于Linux来说就是创建一个新的task_struct,即只需要将原来的父进程task_struct拷贝一份,再对其中的部分属性做修改(如:PID,PPID等)即可,而在fork后父子进程访问这之后的同一份代码,因为代码不可修改,但是由于数据可能被修改,因此不能让父子进程共享同一份数据,那么就该让子进程拷贝一份父进程的数据,但是如果拷贝之后没有对数据进行修改那么又会导致资源的浪费,因此Linux规定在子进程尝试修改数据时,操作系统会为其申请一份新空间(使用多少申请多少),子进程修改这份新空间的数据即可,这样的方式也被称为数据层面的写实拷贝。

而对于fork来说,他是一个函数其内部也有其自己的实现,其内部可能包含:1. 创建子进程task_struct; 2. 填充task_struct;3. 让它指向同一份代码;4. 使它可以被自由调度;......在完成了这一系列的任务之后,子进程已经被创建好了,此时由于父子进程共享同一份代码,到最后的return 语句时,父进程与子进程会各自返回一次数据。

3. 对于id变量,它是怎么做到拥有不同内容的?

在代码中可以看到,pid_t id = fork();这个id就是数据内容,在fork返回两次后,对于id来说发生了数据的写实拷贝。

在了解了进程的创建后,我们对于bash也有了一个新的认识,即它在使用的途中一定会调用fork函数,并用其来创建子进程(执行解释命令)。

4. 进程状态

①一般操作系统学科中的进程状态

1. 运行

这些task_struct已经准备好了,可以随时被调度,此时在队列中的状态称为运行态(R),一般来说在队列中是到了谁就执行谁。那么只要进程放到CPU中,是不是一定要执行完毕所有的内容,才能执行下一个进程呢(如while(1))?答案肯定是否定的,其实对于每个进程都具有一个属性——时间片,有了时间片后,在一段时间内,所有的进程代码都会执行(并发执行)。而在这个过程中,一定会有大量的把进程从cpu上放上与拿下的动作,我们将其称为进程切换。

2. 阻塞

当task_struct对应的数据代码需要从键盘中读取数据时,但是此时却没有输入时,这种状态就称为阻塞状态,此时该task_struct会被链入键盘的waitqueue中,如果下一个需要键盘输入的task_struct直接链入之后的队列即可。

3. 挂起

在阻塞状态时,如果操作系统内部资源不足时,为了保证操作系统维持正常状态而要省出资源,此时操作系统会将task_struct保留,将代码和数据放在外设中(换出),此时的进程状态为挂起,而在需要时会将代码和数据加载回来(换入)。

②Linux中的进程状态

在Linux中定义如下

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

以下面的代码为例

我将其运行后查看

此时的S+(此处的+表示前台运行,不能输入bash命令)表示处于S状态(即阻塞状态),这是因为cpu的运行速度太快,而显示屏运行速度相等较慢,因此有极大的可能性时处于S状态,而我们将代码修改一下

,即可发现

此时,由于不需要等待外设,因此一直处于运行态即R。

对于D状态,我们先举一个具体的例子,

若处于极端情况下时,进程被kill,磁盘写入数据失败时,反馈信息给进程时,进程却不见了,此时磁盘一般会选择丢失这部分数据,那么为了防止这种情况发生,我们只需要让进程在等待磁盘时,不能被杀掉即可,即将其设置为D状态,在磁盘写入完毕后再将其状态修改为S。由此,我们可以认识到S状态属于浅度睡眠,可以随时响应系统的调度,而D状态属于深度睡眠,它不会响应系统调度。

对于T状态,我们可以使用kill的命令来暂停进程,即

查看后,我们知道可以使用-19命令来发出暂停信号, 即

此时我们可以看到mycode处于暂停状态,而对于t状态,我们可以使用gdb来演示

可以看到,当我们使用断点停止在某一处时,此时mycode处于t状态。

对于X状态和Z状态,在一个进程死亡的时候,会先进入Z状态,其目的是需要维持相应的状态,直到被父进程读取到信息后,其状态才会转换成X(瞬时)。

我们以下面的代码举例

运行并监视有

可以看到,在子进程结束,父进程未结束后,子进程处于Z+状态<defunct>(失效的),我们将此状态称为僵尸状态,进程一般退出时,若父进程没有主动回收子进程信息,子进程会一直处于Z状态,这样就会导致资源会被一直占用,就有可能导致内存泄漏。

将代码修改一下

运行并监视有

可以看到,对于操作系统本身来说,若父进程先退出,其子进程的父进程会被修改为1号进程(即操作系统)。对于父进程为1的进程我们将其称为孤儿进程,该进程被操作系统所领养。那么为什么要被领养呢?因为孤儿进程未来也要退出,也需要被释放,而操作系统本身具有回收功能。

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

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

相关文章

polar CTF WEB-veryphp

1、题目 <?php error_reporting(0); highlight_file(__FILE__); include("config.php"); class qwq {function __wakeup(){die("Access Denied!");}static function oao(){show_source("config.php");} } $str file_get_contents("ph…

图神经网络——图学习

图学习 0. 前言1. 图2. 图学习3. 图神经网络小结 0. 前言 近年来&#xff0c;从社交网络到分子生物学等各个领域&#xff0c;数据的图表示越来越普遍。图神经网络 (Graph Neural Network, GNN) 是专为处理图结构数据而设计的&#xff0c;要充分挖掘图表示的潜力&#xff0c;深…

[Ray Tracing: The Rest of Your Life] 笔记

前言 开年第一篇博客~ 整理了三四个小时才整理完orz。 这一部分是光线追踪三部曲的最后一部&#xff0c;主要介绍了蒙特卡洛积分、重要性采样等内容。场景上没有什么大的改变&#xff0c;基本上就是在Cornell Box中渲染的&#xff0c;本篇主要在加速收敛&#xff0c;提升渲染效…

浅析PostgreSQL与SQL Server两者间的关键性差异

市场上有各种各样的数据库可供选择&#xff0c;用户通常可以仔细考虑PostgreSQL与SQL Server&#xff0c;以便为他们的用例找出更好的选择。使用PostgreSQL进行运营的组织可能希望切换到像Microsoft SQL Server这样的数据库&#xff0c;因为它主要迎合不同的数据仓库解决方案、…

学Python到底能干什么?看这里就知道

学Python到底能干什么&#xff1f;看这里就知道 | Python是一种代表简单主义思想的语言&#xff0c;极其容易上手&#xff0c;并且功能非常强大&#xff0c;这也是我的第二计算机语言。 个人可以使用Python去做哪些事呢&#xff1f; ✅办公自动化场景&#xff1a; 每天要处理…

磁盘管理-------磁盘分区

目录 引导语&#xff1a; 一、磁盘分区概念及作用 二、磁盘分区 &#xff08;一&#xff09;添加磁盘 &#xff08;二&#xff09;创建分区 &#xff08;三&#xff09;创建文件系统 &#xff08;四&#xff09;挂载 &#xff08;五&#xff09;永久挂载 三、扩展分区…

ROS学习笔记(7)进一步深入了解ROS第一步

0.前提 最近在学习宾夕法尼亚大学工程学院的ROS公开课&#xff0c;在尽力的去融入全英语的环境&#xff08;哪怕我的英语水准并不是很高&#xff09;。既然是在学习&#xff0c;笔记也就是必须的了&#xff0c;当然这些笔记都是课程当中提出的问题&#xff0c;我去寻找后得出的…

Neuro Contamination - Cyberpunk Gaming Music Futuristic Glitchy Sci-fi

无论是展示赛博朋克未来的电影场景&#xff0c;还是介绍高科技武器&#xff0c;你的音乐选择都至关重要。这首曲子的灵感来自科幻小说&#xff0c;旨在让你的观众想象未来的感觉。 潜在用例&#xff1a;科幻游戏、赛博朋克游戏、电影预告片、动作场景和产品广告。 非常适合充…

一呼百应API实时获取商品详情的实现

一、引言 随着电子商务的飞速发展&#xff0c;快速准确地获取商品详情变得尤为重要。一呼百应作为一家知名的B2B采购平台&#xff0c;提供了丰富的商品信息和交易数据。通过一呼百应的API接口&#xff0c;开发者可以实时获取商品详情&#xff0c;为业务决策和数据分析提供有力…

8868体育助力意甲国际米兰俱乐部 发掘强力新援

意甲的国际米兰俱乐部是8868体育的合作球队之一&#xff0c;国际米兰俱乐部本赛季在意甲联赛中的表现非常出色。他们以不败的成绩排名联赛榜首&#xff0c;展现出了强大的实力和稳定性。最近&#xff0c;有报道称&#xff0c;国米已经与泽林斯基完全达成协议&#xff0c;双方已…

Linux实战:部署基于Postfix 与 Dovecot 的邮件系统

一、电子邮件系统简介 在电子邮件系统中&#xff0c;为用户收发邮件的服务器名为邮件用户代理&#xff08;Mail User Agent&#xff0c;MUA&#xff09;&#xff0c;MTA &#xff08;邮件传输代理&#xff09;的工作职责是转发处理不同电子邮件服务供应商之间的邮件&#xff0…

计算机科学专业选网络安全方向咋样?

结论&#xff1a;慎重选择 原因&#xff1a;不妨看看学校相关方向的培养方案 如果学校真的是想让你成为一流网安人才的话 过来人告诉你&#xff1a; 计科的课你得上 不是计科的课你也得上(一般是数学课&#xff0c;比如密码学&#xff0c;数论) 还得在计算机系统基础实验…

摆烂式学习ssh

摆烂式学习ssh ssh工作原理ssh基本使用sshd配置文件密钥登录1.客户端2.服务器3.注意事项4.使用密钥登录测试 ssh高级使用技巧1.在非正规端口启动2.rsync 命令3.透过 ssh 通道加密原本无加密的服务4.以ssh信道配合x server 传递图形接口5.ssh配合virtualbox虚拟机使用技巧 ssh工…

不知道怎么使用IDEA,一篇文章带你快速上手

前言 IDEA 是由 JetBrains 公司开发的软件产品&#xff0c;全称为 IntelliJ IDEA&#xff0c;一个 Java 语言的集成开发环境。它 —— 在业界被公认为是最好的 Java 开发工具之一&#xff0c;尤其在智能代码助手、代码自动提示、重构、J2EE 支持、Ant、JUnit、CVS 整合、代码审…

MySQL 8.0 InnoDB Tablespaces之Undo Tablespaces(UNDO表空间)

文章目录 MySQL 8.0 InnoDB Tablespaces之Undo Tablespaces&#xff08;UNDO表空间&#xff09;Undo Tablespaces&#xff08;UNDO表空间&#xff09;默认UNDO表空间添加 Undo 表空间查看Undo 相关的信息查看Undo 相关参数变量查看Undo 状态信息通过information_schema.innodb_…

css文本溢出处理——单行、多行

日常开发中&#xff0c;经常会遇到需要展示的文本过长&#xff0c;这种情况下&#xff0c;为了提高用户的使用体验&#xff0c;最常见的处理方式就是把溢出的文本显示成省略号。 处理文本的溢出的方式&#xff1a;1&#xff09;单行文本溢出&#xff1b; 2&#xff09;多行文本…

51单片机中TCON, IE, PCON等寄存器的剖析

在单片机中&#xff0c;如何快速通过名字记忆IQ寄存器中每一个控制位的作用呢&#xff1f; IE&#xff08;interrupt enable&#xff09;寄存器中&#xff0c;都是中断的使能位置。 其中的EA&#xff08;enable all&#xff09;是总使能位&#xff0c;ES(enable serial)是串口…

Find My帽子|苹果Find My技术与帽子结合,智能防丢,全球定位

帽子是戴在头部的服饰&#xff0c;多数可以覆盖头的整个顶部。主要用于保护头部&#xff0c;部分帽子会有突出的边缘&#xff0c;可以遮盖阳光。帽子亦可作打扮之用&#xff0c;也可以用来保护发型、遮盖秃头。可不同种类&#xff0c;例如贝雷帽、鸭舌帽等等。戴帽子在不同的地…

【23-24 秋学期】NNDL 作业13 优化算法3D可视化

编程实现优化算法&#xff0c;并3D可视化 1. 函数3D可视化 分别画出 和 的3D图 代码如下&#xff1a; from mpl_toolkits.mplot3d import Axes3D import numpy as np from matplotlib import pyplot as plt import torch from nndl.op import Op# 画出x**2 class Optimized…