本文主要是介绍进程的理解(基于C语言),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
- 程序与进程
一个可执行程序可以通过进程函数变为进程,如果以shell命令为例子,可以理解为:
1)查找命令对应的程序文件的位置;
2)使用fork函数创建一个进程;
3)在新的进程之中调用exec族装载程序文件,并且调用程序的main函数 - 每一个进程都会有相关的执行状态,大体可以分为运行态,就绪态,睡眠状态,暂停状态,退出状态
可以理解该图为:由暂停或者睡眠转入执行需要先到就绪状态进行中转;而退出状态则无法转为执行状态了。 - 进程环境
进程自身会有进程ID,进程关系分为父进程和子进程,可以获取各自的ID,在进程执行的时候,程序将会获取当前用户的UID和组 ID(GID),作为该 进程执行 的权限;在执行进程时需要获取一些环境变量的资源;执行进程必定涉及到标准输入、输出和错误;
进程ID的获取:getpid()
父进程ID的获取:getppid() ppid指的是parent pid
环境变量:
1)通过 main()函数的第 3 个参数 env 获取 int main(int argc, char *argv[], char *env[]);
2)通过 environ 全局变量获取。在加载进程的时候,系统会为每一个进程复制一份系统环境变量的副本,并保存在全局变量environ中
3)通过 getenv()函数获取。Linux 系统提供 getenv()、setenv()等函数来操作环境变量 - 进程的基本操作:
必要 的操作:创建进程与终止进程,
修改当前 进程的代码空间(exec族函数)
管理和优化进程占用的内存空间:
wait函数:用来帮助父进程获取其子进程的退出状态,当进程退出时,内核为 每一个进程保存一定量的退出状态信息,父进程可以根据此退出信息来判断子进程的运行状态;如果父进程没有调用wait函数,则子进程的退出信息将一直保持在内存中;如果调用了wait函数,则会知道进程的运行状态,并且清除一部分子进程运占用的内存资源;
僵尸进程:如果子进程先终止,但是其父进程没有为它调用wait函数,那么该子进程就会变为僵尸进程,僵尸进程在他的父进程为她调用wait函数之前将一直占有系统的内存资源;
孤儿进程:如果父进程先终止,尚未终止的子进程将会变为 孤儿进程,孤儿进程将会直接被init进程收管,有init进程负责收集 其退出信息;
守护进程:是运行在后台的一种特殊的进程,它独立于控制终端并且周期性的执行某种任务或者等待处理某些发生的时间,它不需要用户输入就能够运行并且提供某种服务。
因为守护进程的父进程就是init进程,就是前文所讲的孤儿进程,因为其真正的父进程在fork出该进之后就先于该进程退出了,然后由init领养了该进程。守护进程不是交互式的程序,没有 控制终端,任何输出都需要特殊处理。例如:Linux系统中的大多数服务器就是通过守护进程实现的,且都通过字母d结尾,比如:sshd,xinetd,crond等。 - 信号:信号又称为软终端信号,用来通知进程发生了异步事件,进程之间可以通过相互发送信号 ,内核也可以因为内部事件而对进程发送信号,信号值通知进程发生了某些事件,不进行数据传递。
- 进程之间的通信:
1)管道方式:管道在Linux中用|表示,即:将一个进程的输出端 连接到另一个进程的输入端。管道又分为 匿名管道跟命名管道,匿名管道通过pipe函数来创建;命名管道由mkfifo创建,创建一个真实存在与文件系统中的管道文件,参数pathname指定了文件名,参数mode指定了文件 的读写权限。其突破了匿名管道无法在无关线程之间通信的限制,使得在同一主机内的额所有进程可以相互通信。
2)共享内存的方式:允许两个不相关的进程访问同一个逻辑内存单元的进程间通信的方法,是在两个 正在运行的进出层间共享和传递数据的有效方式;不同的进程之间共享内存通常要安排为同一段物理内存,进程可以将同一段共享内存连接到自己的地址空间中,所有的进程都可以访问共享内存中的地址,好比malloc分配的内存一样。
3)信号量方式:
这篇关于进程的理解(基于C语言)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!