标签:程序 创建失败 int exec 介绍 变量 内存不足 系统调用 close
进程控制介绍
进程控制中涉及到进程创建、睡眠、退出等,在Linux中提供fork、clone的进程创建方法,sleep的进程睡眠,exit的进程终止调用。
主要的系统调用
下面将具体介绍重要的系统调用的代码实现。
fork()创建进程
我们可输入man 2 fork查看该函数的声明
由图可知函数声明在头文件<unistd.h>中,且fork的类型为pid_t,这个类型与进程标识符PID的类型是一样的,所以我们这样写代码也是OK的:
pid_t pid;
pid = fork();
fork的中文名为分叉,十分形象。在每次执行fork后,就会产生一个新的进程,这样就分叉了,当前进程称为子进程,原来的进程称为父进程。
fork的特点在于一次性返回两个值。先来分析下面的代码:
int main() { int i; if (fork() == 0) { for (i = 1; i < 3; i++) printf("This is child process\n"); } else { for (i = 1; i < 3; i++) printf("This is parent process\n"); } }
执行结果如下:
This is child process This is child process This is parent process This is parent process
if和else里头的代码都执行了,说明fork()的返回值必然一个为0另一个为非0。
通过查阅资料知道,在执行fork()时,由于fork创建了一个子进程,所以fork()会将子进程的PID(进程标识符为一个正值)返回给父进程,而将0返回给刚创建的子进程。如果想得到父进程的PID,用函数getppid(),如果想得到子进程的PID,则用函数getpid(),这两个函数的返回值类型都是int。
额外补充一点,fork()创建失败的话,返回值为-1,失败的具体情况有下两点:
另外我们把for循环的次数放大,比如每个for循环执行5000次,会发现一个有趣的现象,即开始交错打印:
则明显地看到父进程与子进程的并发执行。一般来说是父进程先执行还是子进程先执行是不确定的,这取决于内核所使用的调度算法。但是由于操作系统一般让所有进程都享有相同的执行权,除非另一个优先权更高。所以这里的父进程与子进程的执行会交替进行。
exec函数族执行新程序
一般在子进程中会使用exec函数来执行另一个程序。系统调用exec用于执行一个可执行程序以代替当前的程序,也就是说某进程一旦调用了 exec 类函数,正在执行的程序就被干掉了,系统把代码段替换成新的程序(由 exec 类函数执行)的代码,并且原有的数据段和堆栈段也被废弃,新的数据段与堆栈段被分配,但是进程号却被保留。
所以exec的执行结果为:系统认为该进程还是原来的进程,但是进程里面的程序被替换了。
下面是通过man 3 exec得到的exec函数族的相关信息
这儿出现了一个陌生的外部全局变量 char **environ,这是什么呢? 它是环境变量。
所谓环境变量,就是为了便于用户灵活地使用shell,Linux引入了环境变量的概念,包括了用户的主目录、当前目录、终端类型等,它们定义了用户的工作环境,所以称为环境变量。通过命令env可查看这些环境变量值,或者通过以下方式也能实现查看环境变量值。
extern char **environ; for(i=0; environ[i] != NULL; i++) printf("%s",environ[i]);
未完待续
标签:程序 创建失败 int exec 介绍 变量 内存不足 系统调用 close
原文地址:http://www.cnblogs.com/Bw98blogs/p/7604493.html