每一个进程都有一个唯一的进程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://www.cnblogs.com/yxwkf/p/3813105.html