目录
概述
1 认识进程
1.1 进程的定义
1.2 进程状态
1.3 进程的调用
2 进程环境
2.1 进程ID
2.2 父进程与子进程
2.3 UID 和 GID
2.4 环境变量
2.4.1 通过main函数参数获取环境变量
2.4.2 environ 全局变量获取环境变量
2.4.3 getenv()函数获取环境变量
2.5 环境变量的作用
3 参考文献
概述
本文介绍linux编程中进程的概念,还介绍了进程环境的一些知识,以及如何查询环境变量中参数方法。
1 认识进程
1.1 进程的定义
进程(process) 是一个已经开始执行但还没终止的程序实例。 Linux 系统下使用 ps 命令可以查看到当前正在执行的进程。每个进程包含有进程运行环境、内存地址空间、进程ID、和至少一个被称为线程的执行控制流等资源。同一个程序可以实例化为多个进程实体。操作系统中所有进程实体共享着计算机系统的 CPU、外设等源。
1.2 进程状态
Linux 是一个多用户多任务的操作系统,可以同时运行多个用户的多个程序,就必然会产生多进程,而每个进程都会有不同的状态。 Linux 的进程有以下 6 种状态:
状态 | 描述 |
---|---|
D | 不可中断的深度睡眠状态,处于这种状态的进程不能响应异步信号; |
R | 进程处于运行态或就绪状态, 只有在该状态的进程才可能在 CPU 上运行。而同一时刻可能有多个进程处于可执行状态; |
S | 可中断的睡眠状态,处于这个状态的进程因为等待某种事件的发生而被挂起 |
T | 暂停状态或跟踪状态 |
X | 退出状态,进程即将被销毁 |
Z | 退出状态,进程成为僵尸进程 |
进程的状态转换图如下:
Linux 系统使用“ps -aux”命令时可观察到进程的当前状态
ps -aux
1.3 进程的调用
进程创建后通常要调用 exec 族函数来装载程序文件的可执行映像,并在完成装载后调用程序的 main()函数。在 C 程序中, main()函数通常是程序的执行起始点,有 3 种原型定义:
int main(); /* 原型 1 */
int main(int argc, char *argv[]); /* 原型 2 */
int main(int argc, char *argv[], char *env[]); /* 原型 3 */
函数参数介绍
参数 | 介绍 |
---|---|
argc | 命令行参数的个数 |
argv[] | 指向参数的各个指针所构成的数组 |
env[] | 环境变量字符串的数组 |
2 进程环境
2.1 进程ID
每个进程在创建时,内核都会为之分配一个进程 ID(Process ID,简称 PID)用来标识当前的进程,进程 ID 是一个类型为 pid_t 的整数,并保持同一时刻是唯一值,它最大值为pid_max 值(默认为 32768,可修改)。当进程退出时,它的进程 ID 可回收循环使用。
Linux 系统 getpid()函数可以获取当前进程的进程 ID。 getpid()函数原型如下:
#include <unistd.h>
pid_t getpid(void);
Linux环境下查看进程PID,使用如下命令:
ps -ef
2.2 父进程与子进程
进程创建时,创建进程为新进程的父进程,新进程是创建进程的子进程。在子进程中可 以使用 getppid()函数获取父进程的 PID, getppid()函数原型如下:
#include <unistd.h>
pid_t getppid(void);
Linux 使用进程间的父子关系将所有系统进程组织为一棵树形结构,其中 init 进程为所 有进程的根节点。
使用命令,查看Linux进程结构:
pstree
2.3 UID 和 GID
Linux 是一个多用户的操作系统,每个用户至少有一个用户 ID(User ID,简称 UID)及用户组 ID(Group ID,简称 GID) 。 Linux 系统有严格的权限管理,每个用户有不同的权限,如 root 用户拥有访问所有系统资源的权限。当执行一个程序时,该程序将获取当前用户的 UID 及 GID 作为进程的权限。
使用 id 命令可以列出当前用户的 id:
id root
2.4 环境变量
进程在运行过程中可以通过以下 3 种方式来获取运行环境的环境变量: 1)通过 main()函数的第 3 个参数 env 获取; 2)通过 environ 全局变量获取; 3)通过 getenv()函数获取。
查询linux环境下的环境变量:
env
2.4.1 通过main函数参数获取环境变量
main()的原型的第三个参数为环境变量字符串的指针数组,数组最后一个元素为 NULL。下面看一个具体的实例:
#include <stdio.h>
int main(int argc, char * argv[], char *env[])
{
int i = 0;
while (env[i])
puts(env[i++]);
return 0;
}
2.4.2 environ 全局变量获取环境变量
在加载进程的时候,系统会为每一个进程复制一份系统环境变量的副本, 并保存在全局变量environ中。下面看一个具体的实例:
#include <stdio.h>
extern char ** environ;
int main(int argc, char * argv[])
{
int i = 0;
while (environ[i])
puts(environ[i++]);
return 0;
}
2.4.3 getenv()函数获取环境变量
Linux 系统提供 getenv()、 setenv()等函数来操作环境变量,getenv()函数的原型如下:
#include <stdlib.h>
char *getenv(const char *name);
参数 name 是要获取的环境变量名,返回值为该变量的值。以下代码可以获取环境变量HOME 的值:
char* env;
env = getenv("HOME");
2.5 环境变量的作用
环境变量常见的用途之一是在 shell 中, 每一个环境变量都有它所表示的含义,譬如 HOME 环境变量表示用户的家目录, USER 环境变量表示当前用户名, SHELL 环境变量表示 shell 解析器名称, PWD 环境变量表示当前所在目录等, 在自己的应用程序当中,也可以使用进程的环境变量。
3 参考文献
-
《现代操作系统》
-
《linux/unix系统编程手册》