目录
程序执行时,main函数是如何被调用的,命令行参数是如何传递给程序的,典型的存储空间布局是什么样式,如何分配其他存储空间,进程如何使用环境变量,进程的终止等等这些都是进程控制的基础知识。
进程的启动和终止
进程终止的情况
进程启动和终止图
atexit函数
exit函数
_e(E)xit函数
ISO C 定义这个函数的目的是为进程提供一种无需运行终止处理程序或信号处理函数的方法而终止程序。但ISO C 对标准I/O流是否进行冲洗,这取决于操作系统的实现。在unix中,是不进行冲洗的。
exit和_e(E)ixt函数的状态码
wait和waitpid函数
环境表和环境变量
环境表结构图
环境变量
这些函数如何修改环境表的
内存存储结构补充说明
内存管理结构图
存储空间分配函数
函数间跳转策略
寄存器变量会存在回滚现象的探究
首页 运维 linux运维 进程环境--进程管理

进程环境--进程管理

Jul 23, 2017 am 11:16 AM
环境 进程

程序执行时,main函数是如何被调用的,命令行参数是如何传递给程序的,典型的存储空间布局是什么样式,如何分配其他存储空间,进程如何使用环境变量,进程的终止等等这些都是进程控制的基础知识。


进程的启动和终止

内核执行c程序时,利用exec函数调用一个特殊的启动例程,该启动例程丛内核中获取命令行参数和环境变量值。

进程终止的情况

5种正常终止的情况:

(1)从main函数返回;
(2)调用exit;
(3)调用_exit和_Exit函数;
(4)最后一个线程调用pthread_exit;
(5)最后一个线程从其启动例程返回;
登录后复制

3种异常终止情况

(1)调用abort;
(2)接到一个信号;
(3)最后一个线程对取消请求做出响应;
登录后复制

进程启动和终止图

进程启动和终止图

atexit函数

一个进程最多可以登记32和函数(例如:signal函数),这些函数由exit函数自动调用。在程序终止时调用这些函数,形成终止处理程序,来进行结束进程前的收尾工作。而exit函数通过atexit函数的登记记录来判断调用哪些函数。

exit函数

此函数由ISO C 定义,其操作包括处理终止处理程序,然后关闭所有标准I/O流。需要注意的是,它不会处理文件描述符、多进程(父子进程)以及作业控制。

_e(E)xit函数
ISO C 定义这个函数的目的是为进程提供一种无需运行终止处理程序或信号处理函数的方法而终止程序。但ISO C 对标准I/O流是否进行冲洗,这取决于操作系统的实现。在unix中,是不进行冲洗的。

exit和_e(E)ixt函数的状态码

无论进程怎样结束,它都会在内核上执行同一段代码(由进程启动和退出图可知)。这段代码来关闭所有的文件描述符,释放所有的存储空间。

程序退出后,利用退出码告知该进程的父进程。父进程通过wait或waitpid函数来完成该子进程的善后工作(获取子进程相关信息 释放子进程占用资源)。若父进程没有处理子进程的退出状态,则子进程变成僵死进程。相反的,若父进程在子进程前终止,则子进程变成孤儿进程。孤儿进程会由1号进程(init进程)接收,大致过程如下:

(1)进程终止时,内核逐个检查所有活动的进程;
(2)分析查找该终止进程的子进程;
(3)将该进程的子进程的父进程ID改为1;
登录后复制

wait和waitpid函数

程序正常或异常终止时,内核都会向父进程发送SIGNAL信号。子进程终止是异步事件,所以该信号也是异步信号。而该信号一般会被父进程默认忽略。或者提供一个信号处理函数来善后。wait和waitpid函数就是其中的信号处理函数的一部分。

wait和waitpid函数区别如下:

(1)wait会阻塞调用者进程等待直至第一个终止的子进程到来;
(2)waitpid可以通过参数设置,来实现调用者进程不阻塞,或选择要阻
塞等待的子进程;
登录后复制

这里的调用者指的是父进程

环境表和环境变量

环境表结构图

环境表结构

  • 每个程序都接收到一张环境表

  • 环境表也是一个字符指针数组

  • enrivon叫做环境指针

  • 指针数组叫做环境表

  • 各个指针指向的字符串叫做环境字符串

环境变量

  • unix内核并不检查环境字符串,它们的解释完全取决于各个应用进程

  • 通常在一个shell启动文件中设置环境变量来控制shell的动作

  • 修改或者增加环境变量时,只能影响当前进程以及其后(之前的不行)生成和调用的任何子进程的环境,但不能影响其父进程的环境

和环境变量相关的函数如下:

#include<stdlib.h>
char *getenv(const char *name);
      返回值:指向与name关联的value的指针;若未找到,返回NULL

int putenv(char *str);
                       返回值:若成功,返回0;若出错,返回非0
                       
int setenv(const char *name, const char *value,
            int rewrite);
int unsetenv(const char *name);
                两个函数返回值:若成功,返回0;若出错,返回-1
登录后复制

这些函数如何修改环境表的

环境表和环境字符串通常存放在内存空间的高地址处(顶部)。所以在修改它的值时,内存是不能继续向高地址延伸;但又因为,它之下是各个栈帧,所以也不能向下延伸。如何修改它的值的过程如下:

(1)修改环境表

1)新value <= 旧value,直接覆盖旧value的存储空间
2)新value >= 旧value,调用malloc函数,在堆区开辟新的存储空间,
将新value复制到这里,再将这片存储区首地址写到环境表相应的位置处。
登录后复制

(2)新增环境表

1)新增一个环境变量,调用malloc函数开辟新的存储空间,将原来的环
境表复制到该存储区,其次再添加一个环境变量,然后在尾部赋值为NULL,
最后将environ指向该区域;
2)在 1)过程的基础上,调用realloc函数,多次添加环境变量;
登录后复制

注意:以这种方式修改的环境变量只在当下程序运行时有效,当程序结束时,相应的存储区被系统回收,这些修改就会失效。

内存存储结构补充说明

内存管理结构图

存储空间结构

  • 未初始化数据段(block started by symbol):在程序开始执
    行之前,内核将此段中的数据初始化为0或空指针;

  • 栈:每次函数调用时,其返回地址以及调用者的环境信息(如某些机器寄存器的值)都存放在栈中;

  • 共享库:只需在所有进程都可引用的存储区中保存这种库例程的一个副本;

存储空间分配函数

#include<stdlib.h>
void *malloc(size_t size);
void *calloc(size_t nojy, size_t size);
void *realloc(void *ptr, size_t newsize);
         3个函数返回值:若成功,返回非空指针;若出错,返回NULL
登录后复制
  • malloc函数:初始值不确定;底层通过调用sbrk函数实现;

  • calloc函数:初始值为0;

  • realloc函数:增加或减少以前分配区的长度;当增加长度时,可能将以前分配区的内容移到另一个足够大的区域,以便在分配区末尾增加存储区,而新增存储区初始值不确定(例如:可变数组的使用);

注意:这些动态分配的函数一般在分配存储空间时,会比要求的大。因为在开辟空间的前后部分存储记录管理信息。因此,在使用时,千万不要越界访问,以免造成不可预知的后果。

函数间跳转策略

在c语言中,goto语句是不能跨函数跳转的。尤其是在函数深层调用时的跳转需求,在出错处理的情况下非常有用。

#include<setjmp.h>
int setjmp(jmp_buf env);
          返回值:若直接调用,返回0;若从longjmp返回,返回非0
void longjmp(jmp_buf env, int val);
登录后复制

变量值回滚问题:自动变量和寄存器变量会存在回滚现象。利用volatile属性来避免此类情况的发生。(在给变量赋值时,赋的值回首先存储在内存(存储器变量)中,然后在由cpu取走,存储在cpu的寄存器上(寄存器变量)。在做系统优化时,那些频繁使用的变量,会直接存储到寄存器中而不经过内存。)

寄存器变量会存在回滚现象的探究

在调用setjmp函数时,内核会把当前的栈顶指针保存在env变量中,所以在调用longjmp函数返回该位置时,全局变量、静态变量、易失变量和自动变量如果在调用setjmp和longjmp函数之间它们的值被修改过,是不会回滚到setjmp函数调用之前的值(当然,编译器将auto变量优化为寄存器变量除外)。因为,这些存储器变量的值是存储在内存相应的段中,回到原先栈顶状态时,同样访问的还是原先的内存空间。

然而,对于寄存器变量来说,首先要明确一点:寄存器变量是用动态存储的方式。意思是寄存器变量的值可能存在不同的寄存器中。如果在调setjmp和longjmp函数之间它们的值被修改过,这个值可能不会存到setjmp之前的对其赋值的寄存器中,而在调用longjmp函数后,又回到了调用setjmp函数时的状态。这个时候再读取寄存器变量的值时,读到的是原先那个寄存器中存储的值而不是修改过的那个寄存器中存储的值,所以出现的回滚现象。

以上是进程环境--进程管理的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
2 周前 By 尊渡假赌尊渡假赌尊渡假赌
仓库:如何复兴队友
4 周前 By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island冒险:如何获得巨型种子
3 周前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

解释一下explorer.exe进程是什么 解释一下explorer.exe进程是什么 Feb 18, 2024 pm 12:11 PM

explorer.exe是什么进程在我们使用Windows操作系统的时候,经常会听到一个名词"explorer.exe".那么,你是否好奇这个进程到底是什么?在本文中,我们将详细解释explorer.exe是什么进程以及其功能和作用。首先,explorer.exe是Windows操作系统的一个关键进程,它负责管理和控制Windows资源管理器(Window

com surrogate是什么进程 com surrogate是什么进程 Sep 14, 2022 pm 02:56 PM

“com surrogate”是“C:\Windows\System32\dllhost.exe”的进程;出现该进程通常是“COM+”组件停止工作,这个进程占用高甚至直接未响应,这是由于电脑在加载文件图标的时候出现问题,导致电脑变的卡顿,可以在计算机属性设置中解决卡顿问题。

请问ccsvchst.exe是哪种进程? 请问ccsvchst.exe是哪种进程? Feb 19, 2024 pm 11:33 PM

ccsvchst.exe是一种常见的进程文件,它是SymantecEndpointProtection(SEP)软件的一部分,而SEP则是一款由著名的网络安全公司Symantec开发的终端保护解决方案。作为该软件的一部分,ccsvchst.exe负责管理和监控SEP的相关进程。首先,我们来了解一下SymantecEndpointProtection(

无法引导到Windows恢复环境 无法引导到Windows恢复环境 Feb 19, 2024 pm 11:12 PM

Windows恢复环境(WinRE)是用于修复Windows操作系统错误的环境。进入WinRE后,您可以执行系统还原、出厂重置、卸载更新等操作。如果无法引导到WinRE,本文将指导您使用修复程序解决此问题。无法引导到Windows恢复环境如果无法引导至Windows恢复环境,请使用下面提供的修复程序:检查Windows恢复环境的状态使用其他方法进入Windows恢复环境您是否意外删除了Windows恢复分区?执行Windows的就地升级或全新安装下面,我们已经详细解释了所有这些修复。1]检查Wi

Python和Anaconda之间有什么区别? Python和Anaconda之间有什么区别? Sep 06, 2023 pm 08:37 PM

在本文中,我们将了解Python和Anaconda之间的差异。Python是什么?Python是一种开源语言,非常重视使代码易于阅读并通过缩进行和提供空白来理解。Python的灵活性和易于使用使其非常适用于各种应用,包括但不限于对于科学计算、人工智能和数据科学,以及创造和发展的在线应用程序。当Python经过测试时,它会立即被翻译转化为机器语言,因为它是一种解释性语言。有些语言,比如C++,需要编译才能被理解。精通Python是一个重要的优势,因为它非常易于理解、开发,执行并读取。这使得Pyth

如何正确杀死Linux中的僵尸进程 如何正确杀死Linux中的僵尸进程 Feb 19, 2024 am 10:40 AM

在Linux系统中,僵尸进程是已经终止但仍保留在系统中的特殊进程。虽然僵尸进程不会消耗太多资源,但如果数量过多,可能会导致系统资源耗尽。本文将介绍如何正确清除僵尸进程,以确保系统的正常运行。1Linux僵尸进程子进程完成任务后,如果父进程没有及时检查状态,子进程将成为僵尸进程。子进程在等待父进程确认,完成后系统才会回收。否则,僵尸进程会继续悬挂在系统中。要检查系统中是否存在僵尸进程,可通过运行命令top来查看所有正在运行的进程及可能存在的僵尸进程。‘top’命令的结果从上图可以看到Linux中进

如何在 Windows 11 中停止任务管理器进程更新并更方便地终止任务 如何在 Windows 11 中停止任务管理器进程更新并更方便地终止任务 Aug 20, 2023 am 11:05 AM

如何在Windows11和Windows10中暂停任务管理器进程更新按CTRL+窗口键+删除打开任务管理器。默认情况下,任务管理器将打开“进程”窗口。正如您在此处看到的,所有应用程序都在无休止地移动,当您想要选择它们时,可能很难将它们指向下方。因此,按CTRL并按住它,这将暂停任务管理器。您仍然可以选择应用程序,甚至可以向下滚动,但您必须始终按住CTRL按钮。

Linux进程优先级调整方法详解 Linux进程优先级调整方法详解 Mar 15, 2024 am 08:39 AM

Linux进程优先级调整方法详解在Linux系统中,进程的优先级决定了其在系统中的执行顺序和资源分配情况。合理调整进程的优先级可以提高系统的性能和效率。本文将详细介绍Linux中如何调整进程的优先级,并提供具体的代码示例。一、进程优先级概述在Linux系统中,每个进程都有一个与之相关联的优先级。优先级的范围一般是-20到19,其中-20表示最高优先级,19表

See all articles