每个进程都有一个唯一的进程ID。几个特殊进程:
fork家族函数用于创建子进程(父子进程关系下节具体介绍),子进程往往调用exec家族函数执行新程序(fork+exec操作在有些系统中被称为spawn孵化),而wait家族函数用于获取子进程终止状态。
system函数使用/bin/sh执行命令,以下是使用fork/exec/wait实现的简单版本
#include<sys/wait.h>
#include<errno.h>
#include<unistd.h>
int system(constchar *cmdstring) /* version without signal handling */
{
pid_t pid;
int status;
if (cmdstring == NULL)
return(1); /* always a command processor withUNIX */
if ((pid = fork()) < 0) {
status = -1;
} else if (pid == 0) { /* fork返回值为0,表示是在子进程中*/
execl("/bin/sh", "sh","-c", cmdstring, (char *)0);
_exit(127); /* execl error */
} else { /* 在父进程中,fork返回子进程pid */
while (waitpid(pid, &status, 0) < 0) {
if (errno != EINTR) {
status = -1; /* error other than EINTR fromwaitpid() */
break;
}
}
}
return(status);
}
子进程和父进程共享只读的text段,针对bss段、对、栈,现代操作系统使用COW(copy-on-write)技术,只有发生改变时,才会拷贝相应的内存页。
子进程会继承父进程的大量属性,其中一些重要属性包括:真实/有效用户信息,进程组/会话信息,工作目录,环境变量,资源限制等。
父子进程最明显的区别是:子进程的tms时间统计信息被清零,子进程不会继承文件锁,未决闹钟&信号等(后续章节讨论)。
子进程和父进程返回先后顺序是不确定的,如果用户程序对父子进程执行顺序有依赖,需要自行处理,比如使用信号实现等待通知机制等。
子进程会dup父进程打开的文件描述符(共享文件描述符close-on-exec标记),包括标准输出、输入和错误输出。
如图,父子进程共享file tableentry,位置偏移量一致,所以要父子进程读写同一文件时要注意同步。
之前提到,子进程会继承父进程的uid和euid(有效用户ID),可以调用setuid(setgid)修改进程用户(组)。
struct tms {
clock_t tms_utime; /* user CPU time */
clock_t tms_stime; /* system CPU time */
clock_t tms_cutime; /* user CPU time, terminated children */
clock_t tms_cstime; /* system CPU time, terminated children */
};读书笔记-APUE第三版-(8)进程控制,布布扣,bubuko.com
原文地址:http://blog.csdn.net/idontwantobe/article/details/25245255