linux基础编程:进程基础总结

linux基础编程:进程通信之System V IPC:消息队列,信号量,共享内存 Linux下的进程通信基本上是从Unix平台上的进程通信手段继承而来的。而对Unix发展做出重大贡献的两大主力AT&T的贝尔实验室及BSD(加州大学伯克利分校的伯克利软件发布中心)在进程间通信方面的侧重点有所不同。前者对Unix早期的进程间通信手段进行了系统的改进和扩 充,形成了“system V IPC”,通信进程局限在单个计算机内;后者则跳过了该限制,形成了基于套接口(socket)的进程间通 阅读详情

简介

        程序是一组可执行的静态指令集,而进程(process)是一个执行中的程序实例。利用分时技术,在Linux操作系统上同时可以运行多个进程。分时技术的基本原理是把CPU的运行时间划分成一个个规定长度的时间片,让每个进程在一个时间片内运行。当进程的时间片用完时系统就利用调度程序切换到另一个进程去运行。因此实际上对于具体单个CPU的机器来说某一个时刻只能运行一个进程。但由于每个进程运行的时间片很短(例如15个系统滴答=150ms),所以表面看起来好像所有进程在同时运行着。

  在linux系统中,第一个进程是"手工"建立的,其余的都是进程使用系统调用fork创建的新进程,被创建的进程成为子进程(Child Process),创建者,则称为父进程(parent process)。内核程序使用进程标识号(process ID,pid)来标识每个进程,利用ppid来标识父进程。进程由可执行的指令代码,数据和堆栈区组成。进程中的代码和数据部分分别对应一个可执行文件中的代码段,数据段。每个进程只能执行自己的代码和访问自己的数据及堆栈区。进程之间相互之间的通信需要通过系统调用来进行。对于只有一个CPU的系统,在某一个时刻只能有一个进程正在运行。内核通过进程调度程序分时调度各个进程运行。

  Linux系统中,一个进程可以在内核态(Kernal mode)或者用户态(user mode)下执行,因此Linux内核堆栈和用户堆栈是分开的。用户堆栈用于进程在用户态下临时保存调用函数的参数,局部变量等数据。内核堆栈则含有内核程序执行函数调用时的信息。

        在Linux中,每个进程在创建时都会被分配一个数据结构,称为进程控制块(Process Control Block,简称PCB)。PCB中包含了很多重要的信息,供系统调度和进程本身执行使用,其中最重要的莫过于进程ID(process ID)了,进程ID也被称作进程标识符,是一个非负的整数,在Linux操作系统中唯一地标志一个进程,在我们最常使用的I386架构(即PC使用的架构)上,一个非负的整数的变化范围是0-32767,这也是我们所有可能取到的进程ID。其实从进程ID的名字就可以看出,它就是进程的身份证号码,每个人的身份证号码都不会相同,每个进程的进程ID也不会相同。下面将会详细分析PCB数据结构。

PCB进程控制块

        在linux 中每一个进程都由task_struct 数据结构来定义. task_struct就是我们通常所说的PCB.她是对进程控制的唯一手段也是最有效的手段. 当我们调用fork() 时, 系统会为我们产生一个task_struct结构。然后从父进程,那里继承一些数据, 并把新的进程插入到进程树中, 以待进行进程管理。因此了解task_struct的结构对于我们理解任务调度(在linux 中任务和进程是同一概念)的关键。
        在进行剖析task_struct的定义之前,我们先按照我们的理论推一下它的结构:

  1. 进程状态 ,将纪录进程在等待,运行,或死锁
  2. 调度信息, 由哪个调度函数调度,怎样调度等
  3. 进程的通讯状况
  4. 因为要插入进程树,必须有联系父子兄弟的指针, 当然是task_struct型
  5. 时间信息, 比如计算好执行的时间, 以便cpu 分配
  6. 标号 ,决定改进程归属
  7. 可以读写打开的一些文件信息
  8. 进程上下文和内核上下文
  9. 处理器上下文
  10. 内存信息

        因为每一个PCB都是这样的, 只有这些结构, 才能满足一个进程的所有要求。打开/include/linux/sched.h可以找到task_struct 的定义。

常用的进程操作函数

#include <sys/types.h>
#include <unistd.h>

pid_t getpid(void);
pid_t getppid(void);

获取当前进程ID和父进程ID

#include <unistd.h>

pid_t fork(void);
在Linux中,创造新进程的方法只有一个,就是我们正在介绍的fork。其他一些库函数,如system(),看起来似乎它们也能创建新的进程,如果能看一下它们的源码就会明白,它们实际上也在内部调用了fork。包括我们在命令行下运行应用程序,新的进程也是由shell调用fork制造出来的。fork函数一大特性是:在fork()的调用处,整个父进程空间会原模原样地复制到子进程中,包括指令,变量值,程序调用栈,环境变量,缓冲区,等等。经典的关于fork的面试题: http://coolshell.cn/articles/7965.html

#include <stdlib.h>

int system(const char *command);

该函数是在标准库下的创建进程函数,该函数通过shell启动一个想要执行的程序。由该函数启动的进程结束以后,父进程才继续执行。

#include <unistd.h>

extern char **environ;

int execl(const char *path, const char *arg, ...);
int execlp(const char *file, const char *arg, ...);
int execle(const char *path, const char *arg,..., char * const envp[]);
       
int execv(const char *path, char *const argv[]);
int execvp(const char *file, char *const argv[]);
int execvpe(const char *file, char *const argv[], char *const envp[]);
上面函数主要分为两类。第一类是可变参数,第二类是利用字符串数组。在启动一个新的程序时,把argv数组或者可变序列字符串传给main函数。以字母p结束是PATH路径下搜索程序。全局变量environ可以用来传递一个值到新的程序环境中,函数execle或execvpe可以通过envp传递字符串数组来作为新的环境变量。一般情况下,exec函数是不会返回的。除非发生错误。并且执行exec函数以后,后面的代码空间将被指定的程序覆盖,除非出现错误,后面的代码将不会执行。

#include <stdlib.h>

void exit(int status);

进程退出函数。一个进程调用了exit之后,该进程并非马上就消失掉,而是留下一个称为僵尸进程(Zombie)的数据结构。在Linux进程的5种状态中,僵尸进程是非常特殊的一种,它已经放弃了几乎所有内存空间,没有任何可执行代码,也不能被调度,仅仅在进程列表中保留一个位置,记载该进程的退出状态等信息供其他进程收集,除此之外,僵尸进程不再占有任何内存空间。僵尸进程中保存着很多对程序员和系统管理员非常重要的信息,首先,这个进程是怎么死亡的?是正常退出呢,还是出现了错误,还是被其它进程强迫退出的?其次,这个进程占用的总系统CPU时间和总用户CPU时间分别是多少?发生页错误的数目和收到信号的数目。这些信息都被存储在僵尸进程中,试想如果没有僵尸进程,进程一退出,所有与之相关的信息都立刻归于无形,而此时程序员或系统管理员需要用到,就只好干瞪眼了。
那么,我们如何收集这些信息,并终结这些僵尸进程呢?就要靠我们下面要讲到的waitpid调用和wait调用。这两者的作用都是收集僵尸进程留下的信息,同时使这个进程彻底消失。下面就对这两个调用分别作详细介绍。

#include <sys/types.h>
#include <sys/wait.h>

pid_t wait(int *status);
pid_t waitpid(pid_t pid, int *status, int options);

进程一旦调用了wait,就立即阻塞自己,由wait自动分析是否当前进程的某个子进程已经退出,如果让它找到了这样一个已经变成僵尸的子进程,wait就会收集这个子进程的信息,并把它彻底销毁后返回;如果没有找到这样一个子进程,wait就会一直阻塞在这里,直到有一个出现为止。参数status用来保存被收集进程退出时的一些状态,它是一个指向int类型的指针。但如果我们对这个子进程是如何死掉的毫不在意,只想把这个僵尸进程消灭掉,(事实上绝大多数情况下,我们都会这样想),我们就可以设定这个参数为NULL。

如果参数status的值不是NULL,wait就会把子进程退出时的状态取出并存入其中,这是一个整数值(int),指出了子进程是正常退出还是被非正常结束的,以及正常结束时的返回值,或被哪一个信号结束的等信息。由于这些信息被存放在一个整数的不同二进制位中,所以用常规的方法读取会非常麻烦,人们就设计了一套专门的宏(macro)来完成这项工作,下面我们来学习一下其中最常用的两个:
1,WIFEXITED(status) 这个宏用来指出子进程是否为正常退出的,如果是,它会返回一个非零值。
2,WEXITSTATUS(status) 当WIFEXITED返回非零值时,我们可以用这个宏来提取子进程的返回值,如果子进程调用exit(5)退出,WEXITSTATUS(status)就会返回5;如果子进程调用exit(7),WEXITSTATUS(status)就会返回7。请注意,如果进程不是正常退出的,也就是说,WIFEXITED返回0,这个值就毫无意义。

Linux进程管理:从基础到高级编程技巧 进程是操作系统资源分配的基本单位,Linux通过独特的轻进程模型实现多任务管理。理解进程创建(fork/exec)、状态监控和进程间通信(IPC)机制是系统编程的核心基础。在Linux环境下,进程管理涉及PCB控制块、写时复制等底层原理,通过pipe、FIFO等IPC技术实现高效数据交换。这些技术支撑了从简单脚本到复杂服务器架构的开发,特别是在高并发、分布式系统等场景中,合理的进程管理能显著提升系统稳定性和性能。本文以C语言为例,深入解析Linux进程管理的核心技术,包括进程控制、资源回收和现代容器技术基础 阅读详情

相关推荐

linux基础编程:进程通信之套接字

在文章《linux基础编程:进程通信之System V IPC:消息队列,信号量,共享内存》开头部分,我们介绍了linux环境下的进程通信方式IPC分类。本节我们将介绍由贝尔实验室及BSD(加州大学伯克利分校的伯克利软件发布中心)提出的IPC工具:套接字接口。 套接字机制是管道概念的一个扩展。凭借这种机制,客户或者服务器系统的开发工作既可以在本地单机运行,也可以跨网络进行分布式进程间进行。但是套

ColZer的专栏 2060

linux基础编程:进程通信之管道

在文章《linux基础编程:进程通信之信号》中,我们看到信号作为进程之间的通信方式。但是传送的信息之限于一个信号值。而本文将会介绍Linux支持的最初Unix IPC之一:管道和命名管道,它允许进程之间交换更多的数据,管道指的是从一个进程连接数据流到另一个进程。它具有以下特点: 管道是半双工的,数据只能向一个方向流动;需要双方通信时,需要建立起两个管道;只能用于父子进程或者兄弟进程之间(

ColZer的专栏 1479

高通 Gen AI 推理扩展 (GENIE)(5):实战指南与Engine API深度解析

本文深入解析高通Gen AI推理扩展(GENIE)的Engine API核心功能与实战应用,涵盖引擎实例化、多引擎动态切换、性能调优及跨平台部署等关键技巧。通过详细代码示例和性能数据,帮助开发者高效利用GENIE进行AI推理,提升应用性能与稳定性。

weixin_29065959的博客 464

Linux编程基础:第6章Linux进程管理 课后习题

《Linux编程基础》黑马程序员/编著清华大学出版社 目录 一、填空题 二、判断题 三、单选题 四、简答题 1、简单说明程序和进程的区别。 2、分析程序,写出程序的执行结果。 五、编程题 1、编写程序,在程序中创建一个子进程,使父子进程分别打印不同的内容。 2、编写程序,在程序中创建一个子进程,使子进程通过exec更改代码段,执行cat命令。 一、填空题 1、进程的属性保存在一个被称为(进程控制块/PCB)的结构体中,这个结构体中包括(进程控制符/PID)、进程组、进程环境、进.

WHT869706733的博客 8402

LAMMPS实操系列(四): 高熵合金FCC-CoCrCuFeNi的退火模拟

我们对FCC-CoCrCuFeNi的退火模拟思路主要是,首先将材料以均匀的速率用100 ps从300 K升温至1000 K,然后在1000 K的温度下平衡100 ps,随后以均匀的速率用100 ps从1000 K降温至300 K,随后通过共轭梯度下降法做静力学结构优化得到退火后的结构。由于FCC-CoCrCuFeNi高熵合金被认为是潜在的工程结构材料[1],接下来我们将对退火前后的结构进行压缩模拟,对比退火前后FCC-CoCrCuFeNi高熵合金的力学性能变化,敬请各位读者关注我们的更新。

Ceshigo_CD的博客 4837

LAMMPS in文件详解:从零开始手把手教你配置金属分子动力学模拟

本文详细解析了LAMMPS in文件的配置方法,手把手教你完成金属分子动力学模拟的全流程。从软件环境准备、势函数选择,到使用Materials Studio构建模型、编写in文件进行能量最小化与系统弛豫,再到实施单轴拉伸生产模拟并提取应力应变数据,最后通过Python和OVITO进行结果分析与可视化,提供了完整的实战指南和常见问题排查技巧。

weixin_28475533的博客 527

Linux编程:2、进程基础知识

getpid()/var/run进程名.pidfcntl。

m0_75107602的博客 1275

ollama环境变量配置:修改ollama的数据路径(安装路径)

ollama安装模型,如果很大,会占用C盘空间,影响系统运行速度,通过设置环境变量,来改变ollama放目录的地址。

正经教主是个热衷于正经学习分享的教主。 1万+

Linux 系统编程 04:进程基础

本文深入讲解了Linux进程管理的核心概念与fork机制。首先区分程序与进程,介绍进程控制块(PCB)和三种基础状态。重点解析fork系统调用的特性:一次调用两次返回,通过返回值区分父子进程。详细剖析写时复制(Copy-on-Write)机制,说明父子进程的资源共享与差异,特别是文件描述符的共享特性。对比分析了fork与已淘汰的vfork的区别,并总结了面试高频考点与常见误区。理解进程创建机制是学习后续进程控制与通信的基础。文章为技术人员提供了全面系统的进程创建知识体系,是Linux系统编程的重要基础内容。

x1649545783的博客 431

【目录】专栏文章导航

从最强工具链Davinci Configurator模块学习出发掌握AUTOSAR

weixin_47571898的博客 3294

相机Camera日志分析之二:高通CamX架构对应Google原生Camera HAL3架构的标准API接口一级日志详细分析注释

【思维决定成长高度】当前讲述的是Camera领域log分析梯度分级讲解,讲究的是一种分析技巧,分析思维,一种感悟。技术路线的提升空间,需要更多开发技巧和开发学习能力去提升。技术大拿分析问题,可以从日志快速定位问题并解决问题,有充分的时间去学习更多知识,成长速度极快。同一起跑线,学习能力,开发效率等等都决定了程序员的成长提升空间。记得我毕业三年,同学之间的差距无限拉大,一些人还在几千块薪水,你已经是他的四五倍了,人与人的差距就是短短几年就拉开了。

429

Linux系统编程:进程基础

文章内容程序与进程虚拟存储器/虚拟地址空间gdb调试功能进程状态常用命令 程序与进程 进程:运行中的程序 虚拟存储器/虚拟地址空间 gdb调试功能 步骤 操作 意义 1 g++ test.cpp -g 编译时加 -g 2 gdb ./a.out 开始调试 3 list 查看断点 4 b 5 断点加在第5行 5 info proc mapping 查看内存区域的映射 6 n next走到下一步 7 p handle 查看handle的地址 8 q 退出 进程状

凯凯在此 822

【WRF数据准备】土地利用数据-MODIS MCD12Q1数据下载及制备

【WRF数据准备】MODIS静态地理数据下载及制备

WW、forever的博客 3413

Linux系统编程基础:进程控制

Linux进程控制

小青菜的博客 1279

【DRAM存储器四十七】LPDDR5介绍--LPDDR5的低功耗技术之DVFS

讲述LPDDR5的DVFSC和DVFSQ的工作原理和要求

highman110的博客 899

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

Linux编程基础:进程管理2

一、进程管理 1.exec函数族 使用fork()函数创建的子进程,其中包含的程序代码完全相同,只能根据fork()函数的返回值,执行不同的代码分支。 由exec函数族中的函数,则可以根据指定的文件名或路径,找到可执行文件。 fork:子进程复制父进程的堆栈段和数据段,子进程一旦开始运行,它继承了父进程的一切数据,但实际上数据却已经分开,相互之间不再影响 exec:一个进程调用exec类函数,它本身就"死亡"了,系统把代码段替换成新的程序代码,废弃原有数据段和堆栈段,并为新程序分配新数据段与堆栈段 ex

Terry_21的博客 1154

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

Linux系统编程基础:进程操作实战

进程是程序执行时的一个实例,包含了程序的执行状态、内存空间、打开的文件描述符等资源。每个进程都有一个唯一的进程ID(PID)和父进程ID(PPID)。本文详细介绍了Linux进程操作的基础知识,包括进程的创建、执行、终止、等待和信号处理。通过实战示例,读者可以更好地理解这些概念,并在实际编程中灵活运用。掌握进程操作是进行Linux系统编程的重要基础,希望本文对读者有所帮助。

宁可搬砖百片,不造轮子一边的博客 377

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

Linux系统编程1:进程基础

Linux系统编程1:进程基础 程序与进程 如果程序是菜谱,进程就是厨师烹饪; 如果程序是乐谱,进程就是乐师演奏; 如果程序是剑谱,进程就是剑客舞剑; 如果程序是棋谱,进程就是棋士复盘; 程序是静的,进程是动的。 进程与程序区别 概念 进程:程序在计算机上的一次执行过程,执行中的程序。 进程是一个抽象概念 本质 程序在地址空间中按照代码逻辑控制流执行 资源分配最小单位 从代码到程序 从程序到进程 内核将程序读入内存,为程序镜像分配内存空间。 内核为该进程分配进程标志符PID。 内核为该

Sunrise的博客 239

Linux进程编程:从基础概念到实践应用

进程是操作系统资源分配和调度的基本单位,Linux系统通过虚拟内存和上下文切换机制实现多进程并发执行。从技术实现看,每个进程拥有独立的地址空间,包含代码段、数据段、堆和栈等关键内存区域,并通过PID进行唯一标识。进程编程的核心价值在于实现任务并行化和资源隔离,广泛应用于服务器守护进程、系统服务等场景。通过fork()系统调用可以创建新进程,而ps命令则是监控进程状态的实用工具。理解Linux进程的内存布局和生命周期管理,是开发高性能、稳定服务的基础。

weixin_32324637的博客 544

Linux编程基础 :进程同步

学习目标:Linux编程基础:进程同步 1.wait函数 2.waitpid函数 3运行案例 学习内容: wait函数 #include <sys/wait.h> pid_t wait(int *status); 运行案例: waitpid函数 运行代码运行案例: 学习时间 2002/5/11 学习产出: 了解了特殊进程的危害 与Java进程类比进行学习 学会了进程的wait函数与waitpid函数 孤儿进程永远不会成为僵尸进程 ...

weixin_51789582的博客 167

Linux编程基础 :进程管理

一、进程控制 1.创建单个进程 #include <unistd.h> pid_t fork(void); frok函数功能 创建进程;函数执行后,系统会创建一个与原进程几乎相同的进程,之后父子进程都继续执行,如图所示: 返回值说明 成功:返回两个值,子进程创建成功后,原程序会被复制,就有了两个fork函数。父进程的fork函数会返回子进程的pid,子进程的fork函数会返回0。 不成功:若子进程创建失败,原程序不会复制,父进程的fork函数返回-1。 案例 使用fork函数创建一个进程,

Terry_21的博客 305

一、Linux系统编程:进程基础

进程基础

小脑斧的博客 503

Linux编程基础 3.1:进程控制

1 进程控制 fork() exec函数族 wait() exit() 1.1 创建进程 #include <unistd.h> pid_t fork(void); 功能:创建进程;函数执行后,系统会创建一个与原进程几乎相同的进程,之后父子进程都继续执行,如图所示: 图 fork函数创建子进程 参数说明:无 返回值说明: 成功:返回两个值,子进程创建成功后,原程序会被复制,就有了两个fork函数。父进程的fork函数会返回子进程的pid,子进程的fork函数会返回0. 不成功:若子进程创建

爱学习爱运动的专栏 3154

Linux编程基础 :进程管理2

文章目录前言一、exec函数族1.exec函数族作用2.exec()系列函数3.案列二、进程退出1.exit函数2._exit函数三、 特殊进程1.特殊进程分类2.特殊进程危害四、 进程同步1.wait函数总结 前言 一、exec函数族 1.exec函数族作用 exec函数族的作用是根据指定的文件名找到可执行文件,并用它来取代调用进程的内容,主要是在fork()之后,它会诱导fork后的子进程另起炉灶,但是PID不变,自己开创一片新天地,清空原来的堆栈区、代码区和数据区,让新的可执行程序完全替代现有的资

layPluto的博客 329

linux基础编程:进程通信之信号

信号本质 信号是在软件层次上对硬件的中断机制的一种模拟,在原理上,一个进程接受到一个信号和处理器接受到中断请求可以说是一样。信号是异步的,一个进程不必通过任何操作来等待信号的到达,事实上,进程也不知道信号到底什么时候到达。信号是进程间通信机制中唯一的异步通信机制,可以看作是异步通知,通知接收信号的进程有哪些事情发生了。信号机制经过POSIX实时扩展后,功能更加强大,除了基本通知功能外,还

ColZer的专栏 1953
上一篇: linux 基础编程:文件操作总结
下一篇: 十亿级别规模KV型数据持久性存储引擎:Leveldb实现原理
ColZer
博客等级 码龄14年 42粉丝 16原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值