UNIX环境高级编程——进程环境

news2024/11/28 18:53:18

7.1 引言

本章主要讲解了进程的环境。

7.2 main函数

C程序总是从main函数开始执行,其函数原型为:

int main(int argc, char *argv[]);
  • argc是命令行参数的数目,argv是指向参数的各个指针所构成的数组;
  • 当内核执行C程序时(使用一个exec函数),在调用main函数前先调用一个特殊的启动例程。可执行程序文件将此启动例程指定为程序的起始地址——这是由连接编辑器设置的,而连接编辑器则由C编译器调用。启动例程从内核取得命令行参数和环境变量值,然后为按上述方式调用main函数做好安排。

7.3 进程终止

有8种方式使进程终止,其中5种为正常终止,它们是:

  • main返回;
  • 调用exit
  • 调用_exit_Exit
  • 最后一个线程从其启动例程返回;
  • 从最后一个线程调用pthread_exit

异常终止有3种方式,它们是:

  • 调用abort
  • 接到一个信号;
  • 最后一个线程对取消请求做出响应。

启动例程使得从main返回后立即调用exit函数。

退出函数

3个函数用于正常终止一个程序:_exit_Exit立即进入内核,exit则先执行一些清理处理,然后返回内核:

#include <stdlib.h>
void exit(int status);
void _Exit(int status);

#include <unistd.h>
void _exit(int status);
  • exit函数总是执行一个标准I/O库的清理关闭操作:对于所有打开流调用fclose函数,输出缓冲中的所有数据都被冲洗(写到文件上);
  • 3个退出函数都带一个整型参数,称为终止状态(或退出状态);
  • main函数返回一个整型值与用该值调用exit是等价的。

atexit函数

一个进程可以登记多至32个函数,这些函数将由exit自动调用,称为终止处理程序,用atexit函数来登记这些函数:

#include <stdlib.h>

int atexit(void (*func)(void));
										// 返回值:若成功,返回0;若出错,返回非0
  • atexit的参数是一个函数地址,当调用此函数时无需向它传递任何参数,也不期望它返回一个值;
  • exit调用这些函数的顺序与它们登记时候的顺序相反,同一函数如若登记多次,也会被调用多次。

exit首先调用各终止处理程序,然后关闭(通过fclose)所有打开流;如若程序调用exec函数族中的任一函数,则将清除所有已安装的终止处理程序。
在这里插入图片描述

  • 内核使程序执行的唯一方法是调用一个exec函数;
  • 进程自愿终止的唯一方法是显式或隐式地(通过调用exit)调用_exit_Exit
  • 进程也可非自愿地由一个信号使其终止。

7.4 命令行参数

  • 当执行一个程序时,调用exec的进程可将命令行参数传递给该新程序;
  • argv[argc]是一个空指针。

7.5 环境表

每个程序都接收到一张环境表,环境表是一个字符指针数组,其中每个指针包含一个以null结束的C字符串的地址,全局变量environ则包含了该指针数组的地址,称之为环境指针

extern char **environ;

在这里插入图片描述

7.6 C程序的存储空间布局

C程序一直由下列几部分组成:

  • 正文段:这是由CPU执行的机器指令部分。通常,正文段是可共享的,所以即使是使用频繁执行的程序在存储器中也只需有一个副本,另外,正文段常常是只读的,以防止程序由于意外而修改其指令;

  • 初始化数据段:通常将此段称为数据段,它包含了程序中需明确地赋初值的变量,例如,C程序中任何函数之外的声明:

    int maxcount = 99;
    

    此变量以其初值存放在初始化数据段中;

  • 未初始化数据段:通常将此段称为bss段(block started by symbol),在程序开始执行之前,内核将此段中的数据初始化为0空指针,函数外的声明:

    long sum[1000];
    

    此变量存放在非初始化数据段中;

  • 自动变量以及每次函数调用时所需保存的信息都存放在此段中;

  • :通常在堆中进行动态存储分配。
    在这里插入图片描述

由上图可以看出:

  • 栈从高地址向低地址方向增长;
  • 未初始化数据段的内容并不存放在磁盘程序文件中;
  • 需要存放在磁盘程序文件中的段只有正文段和初始化数据段。

7.7 共享库

  • 共享库使得可执行文件中不再需要包含公用的库函数,而只需在所有进程都可引用的存储区中保存这种库例程的一个副本;
  • 程序第一次执行或者第一次调用某个库函数时,用动态链接方法将程序与共享库函数相链接;
  • 共享库减少了每个可执行程序的长度,但增加了一些运行时间开销;
  • 共享库使得可以用库函数的新版本代替老版本而无需对使用该库的程序重新连接编辑。

7.8 存储空间分配

3个用于存储空间动态分配的函数:

  • malloc:分配指定字节数的存储区,此存储区中的初始值不确定;
  • calloc:为指定数量指定长度的对象分配存储空间,该空间中的每一位(bit)都初始化为0;
  • realloc:增加或减少以前分配区的长度,当增加长度时,可能需要将以前分配区的内容移到另一个足够大的区域,以便在尾端提供增加的存储区,而新增区域内的初始值则不确定。
#include <stdlib.h>

void *malloc(size_t size);
void *calloc(size_t nobj, size_t size);
void *realloc(void *ptr, size_t newsize);
										// 3个函数返回值:若成功,返回非空指针;若出错,返回NULL
void free(void *ptr);
  • 特别地,若realloc的参数ptr为空指针,则realloc的功能与malloc相同。

7.9 环境变量

getenv函数用于获取环境变量值:

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

以下3个函数用于设置环境变量:

#include <stdlib.h>
int putenv(char *ptr);
										// 返回值:若成功,返回0;若出错,返回非0
int setenv(const char *name, const char *value, int rewrite);
int unsetenv(const char *name);
										// 两个函数的返回值:若成功,返回0;若出错,返回-1
  • putenv取形式为name=value的字符串,将其放到环境表中,如果name已经存在,则先删除其原来的定义;
  • setenvname设置为value,如果在环境中name已经存在,那么:
    (a)若rewrite非0,则首先删除其现有的定义;
    (b)若rewrite为0,则不删除其现有定义(name不设置为新的value,而且也不出错);
  • unsetenv删除name的定义,即使不存在这种定义也不算出错。

7.10 函数setjmp和longjmp

在C中,goto语句是不能跨越函数的,而执行这种类型跳转功能的是函数setjmplongjmp,它们在栈上跳过若干调用帧,返回到当前函数调用路径上的某一个函数中:

#include <setjmp.h>

int setjmp(jmp_buf env);
										// 返回值:若直接调用,返回0;若从longjmp返回,则为非0
void longjmp(jmp_buf env, int val);
  • 在希望返回到的位置调用setjmp
  • setjmp参数env的类型是一个特殊类型jmp_buf,是某种形式的数组,其中存放在调用longjmp时能用来恢复栈状态的所有信息,因为需要在另一个函数中引用env变量,所以通常将env变量定义为全局变量
  • 当检查到一个错误时,以两个参数调用longjmp函数,第一个是在调用setjmp时所用的env,第二个是具非0值的val,它将成为从setjmp处返回的值。

自动变量、寄存器变量和易失变量

  • 如果不想让自动变量值回滚,可定义其为具有volatile属性;
  • 声明为全局变量或静态变量的值在执行longjmp时保持不变。

自动变量的潜在问题

  • 声明自动变量的函数已经返回后,不能再引用这些自动变量。

7.11 函数getrlimit和setrlimit

每个进程都有一组资源限制,进程的资源限制通常是在系统初始化时由0进程建立的,然后由后续进程继承:

#include <sys/resource.h>

int getrlimit(int resource, struct rlimit *rlptr);
int setrlimit(int resource, const struct rlimit *rlptr);
										// 两个函数返回值:若成功,返回0;若出错,返回非0

对这两个函数的每一次调用都指定一个资源以及一个指向下列结构的指针:

struct rlimit {
	rlim_t	rlim_cur;	/* soft limit: current limit */
	rlim_t	rlim_max;	/* hard limit: maximum value for rlim_cur */
};

在更改资源限制时,须遵守下列3条规则:

  • 任何一个进程都可将一个软限制值更改为小于或等于其硬限制值;
  • 任何一个进程都可降低其硬限制值,但它必须大于或等于其软限制值,这种降低,对普通用户不可逆;
  • 只有超级用户进程可以提高硬限制值。

这两个函数的resource参数取下列值之一:
在这里插入图片描述

7.12 实例代码

chapter7

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

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

相关文章

SpringBoot集成Kafka详解

一、使用idea创建SpringBoot项目 1.1 使用Spring Initializr创建一个SpringBoot程序 点击Next。 1.2 添加依赖 依赖说明&#xff1a; Lombok简化实体类开发。 Spring Web让项目集成web开发所有依赖&#xff0c;包括Spring MVC&#xff0c;内置tomcat等。 Spring for Apache…

HNU-操作系统OS-2023期中考试复习-刷题

往年期中卷极难获得&#xff0c;这里找了几套卷子。可以看看。 因为往年都是从第一周开始上课的&#xff0c;所以进度会快一点&#xff0c;这学期是从第四周开始上课的&#xff0c;所以进程会慢些&#xff0c;讲到第九章所以只考到第九章。 同样因为太忙了&#xff0c;答案找…

图像分类卷积神经网络模型综述

图像分类卷积神经网络模型综述遇到问题 图像分类&#xff1a;核心任务是从给定的分类集合中给图像分配一个标签任务。 输入&#xff1a;图片 输出&#xff1a;类别。 数据集MNIST数据集 MNIST数据集是用来识别手写数字&#xff0c;由0~9共10类别组成。 从MNIST数据集的SD-1和…

ctfshow web入门web119-124

1.web119 和118题类似&#xff0c;只不过是过滤了PATH 0可以用任何字符代替&#xff0c;比如A,{A},A,{0} KaTeX parse error: Expected }, got # at position 2: {#̲SHLVL}1&#xff0c;或者{##},${#?} {PHP_VERSION:~A}2,php版本为x.x.2时 ${#IFS}3(linux下是3&#xff0c;…

IntelliJ IDEA 2023.1正式发布,Maven项目大提速支持Apache Dubbo

你好&#xff0c;我是YourBatman&#xff1a;做爱做之事❣交配交之人。 &#x1f4da;前言 一年一个大版本&#xff0c;共计3个中型版本&#xff0c;北京时间2023年3月月29日终于迎来了IntelliJ IDEA今年的首个版本2023.1。老规矩&#xff0c;吃肉之前&#xff0c;可以先把这…

顺丰科技x腾讯安全iOA联合案例获云安全联盟CSA 2022安全革新奖

近年来&#xff0c;随着云计算、大数据、物联网等技术的加速创新和应用&#xff0c;一场数字化的变革开始席卷各行各业。远程办公、业务协同、分支互联等需求涌现&#xff0c;随之而来的还有更加复杂多元的高级网络攻击。在此背景下&#xff0c;传统的基于边界的网络安全防护理…

矩阵键盘+CH559制作国产USB矩阵键盘

矩阵键盘+CH559制作国产USB矩阵键盘 文章目录 矩阵键盘+CH559制作国产USB矩阵键盘为什么选择CH559作为主控芯片?如何实现该款矩阵USB键盘?如何将矩阵键盘的信号转化为USB键盘信号?原材料: 矩阵键盘(附带行列键码定义)CH559开发板将矩阵键盘的所有排线连接到单片机的GPIO引…

基于stm32mp157 linux开发板ARM裸机开发教程5:ARM微处理器指令系统(连载中)

前言&#xff1a; 目前针对ARM Cortex-A7裸机开发文档及视频进行了二次升级持续更新中&#xff0c;使其内容更加丰富&#xff0c;讲解更加细致&#xff0c;全文所使用的开发平台均为华清远见FS-MP1A开发板&#xff08;STM32MP157开发板&#xff09; 针对对FS-MP1A开发板&…

Python | Python的自我介绍(前世今生)

本文概要 本篇文章主要介绍Python这门语言的前世今生&#xff0c;适合刚入门的小白或者想了解Python历史的同学&#xff0c;文中描述很详细&#xff0c;具有一定的学习价值&#xff0c;感兴趣的小伙伴快来一起学习吧。 个人简介 ☀️大家好&#xff01;我是新人小白博主朦胧的…

【机器学习】样本不均衡(class-imbalance)——解决方案与问题思考

目录问题提出问题重述与再理解第一个问题&#xff1a;假如样本不均衡&#xff0c;哪种分类器的泛化性能较好&#xff1f;第二个问腿&#xff1a;在样本不均衡的情况下&#xff0c;如何获得更健壮的模型问题解决方法样本不均衡对机器学习模型会造成什么影响什么模型适合样本不均…

小黑今天上午着急忙慌实习公司楼下笔试,晚上准备和尚香疯狂星期四明天继续现场笔试的leetcode之旅:1091. 二进制矩阵中的最短路径

小黑代码1 class Solution:def shortestPathBinaryMatrix(self, grid: List[List[int]]) -> int:# 一定无解的情况if grid[0][0] 1 or grid[-1][-1] 1:return -1# 矩阵长度n len(grid)# 起点即终点if n 1:return 1# 访问集合seen {(0, 0)}# 初始化队列q collections.…

射频功率放大器在空气耦合超声检测系统中的应用

实验名称&#xff1a;空气耦合超声检测系统研究方向&#xff1a;超声测试设备&#xff1a;ATA-8202射频功率放大器、探头、ATA-5620前置放大器、超声波接收器、数据采集卡、计算机。实验过程&#xff1a;图&#xff1a;空气耦合超声检测锂电池系统锂电池空气耦合超声检测具体过…

TryHackMe-Year of the Dog(Linux渗透测试)

Year of the Dog 谁知道呢&#xff1f;狗咬了一口&#xff01; 端口扫描 循例nmap Web枚举 进80 用gobuster扫了一圈没有任何发现&#xff0c;图像也没有隐写 在主页的请求头的cookie有一个id 改成其他错误值会导致异常&#xff0c;看见叫id&#xff0c;习惯性加个了引号 爆…

【java】集合类

文章目录集合根接口LIST列表迭代器Queue|Deque|PriorityQueueSet集合HashSetLinkedHashSetTreeSet键盘读入MapHashMapLinkedHashMapStream流stream()ints()Collections工具类集合根接口 所有的集合类最终都是实现自集合根接口的&#xff0c;比如ArrayList类&#xff0c;它的祖先…

走向国际市场,怎样用Facebook广告抢占商机?

在当今全球化的商业世界中&#xff0c;企业要想在国际市场中占据一席之地&#xff0c;除了打造优质产品和服务外&#xff0c;有效的营销手段也是至关重要的。 而Facebook作为全球最大的社交媒体平台&#xff0c;其广告投放服务为企业提供了一个快速、便捷、有效的推广途径。那…

安全校验和框架---JWT和Shrio

安全架构 加密 分类 可逆加密和不可逆加密 不可逆加密&#xff1a;常见的不可逆加密算法有MD5&#xff0c;HMAC&#xff0c;SHA1、SHA-224、SHA-256、SHA-384&#xff0c;和SHA-512&#xff0c;其中SHA-224、SHA-256、SHA-384&#xff1b; 可逆加密分为对称加密和非对称加密…

2023最新面试题-Java-5

自定义类加载器 1. 为什么需要自定义类加载器 网上的大部分自定义类加载器文章&#xff0c;几乎都是贴一段实现代码&#xff0c;然后分析一两句自定义ClassLoader的 原理。但是我觉得首先得把为什么需要自定义加载器这个问题搞清楚&#xff0c;因为如果不明白它的作用的情况 …

人工智能动物农场的猪、牛和蟑螂

人工智能动物农场的猪、牛和蟑螂 农业正在成为由人工智能驱动的以数据为中心的业务。中国的大型科技公司正在使用神经网络支持的计算机视觉、可穿戴设备和预测分析算法来重新构想猪、鸡、牛、鹅和蟑螂养殖。 《南华早报》报道称&#xff0c;好医生制药集团每年在中国东南部的四…

OpenHarmony社区运营报告(2023年3月)

目录 本月快讯 一、代码贡献 二、生态进展 三、社区治理 五、社区活动 六、社区及官网运营 本月快讯 • 《OpenHarmony 2022年度运营报告》于3月正式发布&#xff0c;2022年OpenAtom OpenHarmony&#xff08;以下简称“OpenHarmony”&#xff09;开源项目潜心务实、深耕发展&am…

优化Key顺序提升ClickHouse查询性能

ClickHouse 键列顺序不仅影响表压缩效果&#xff0c;对查询性能也有很大影响&#xff0c;正确使用键列的顺序可以跳过大粒度数据范围&#xff0c;提高查询效率。本文通过示例进行测试不同场景的查询性能&#xff0c;从而让我们了解如何选择键列及其顺序。 测试数据 首先创建并…