APUE第八章 进程控制
1、获取进程标识符
#include <unistd.h>
pid_t getpid(void);
pid_t getppid(void);
uid_t getuid(void);
uid_t geteuid(void);
gid_t getgid(void);
gid_t getegid(void);
2、进程创建
#include <unistd.h>
pid_t fork(void);
Returns: 0 in child, process ID of child in parent, −1 on error
#include <unistd.h>
pid_t fork(void);
描述:fork函数是如何做到执行一次返回两次的?首先必须有一点要清楚,函数的返回值是储存在寄存器eax中的。其次,当fork返回时,新进程会返回0是因为在初始化任务结构时,将eax设置为0;在fork中,把子进程加入到可运行的队列中,由进程调度程序在适当的时机调度运行。也就是从此时开始,当前进程分裂为两个并发的进程。无论哪个进程被调度运行,都将继续执行fork函数的剩余代码,执行结束后返回各自的值。
vfork与fork的区别是,vfork并不将父进程的地址空间完全复制到子进程中,而且vfork保证子进程先运行。
3、wait和waitpid函数
#include <sys/wait.h>
pid_t wait(int *statloc);
pid_t waitpid(pid_t pid, int *statloc, int options);
#include <sys/wait.h>
int waitid(idtype_t idtype, id_t id, siginfo_t *infop, int options);
#include
#include
#include
#include
<sys/types.h>
<sys/wait.h>
<sys/time.h>
<sys/resource.h>
pid_t wait3(int *statloc, int options, struct rusage *rusage);
pid_t wait4(pid_t pid, int *statloc, int options, struct rusage *rusage);
当一个进程正常或者异常终止的时,内核就像其父进程发送SIGCHLD信号。
调用wait或waitpid的进程可能会发生以下情况:
如果其所有子进程都还在运行,则父进程阻塞;
如果一个子进程已经终止,正等待父进程获取其终止状态,则取得该子进程的终止状态立即返回。
如果他没有任何子进程,则立即出错返回。
4、exec函数族
#include <unistd.h>
int execl(const char *pathname, const char *arg0, ... /* (char *)0 */ );
int execv(const char *pathname, char *const argv[]);
int execle(const char *pathname, const char *arg0, ...
/* (char *)0, char *const envp[] */ );
int execve(const char *pathname, char *const argv[], char *const envp[]);
int execlp(const char *filename, const char *arg0, ... /* (char *)0 */ );
int execvp(const char *filename, char *const argv[]);
int fexecve(int fd, char *const argv[], char *const envp[]);
描述:exec函数并不创建新进程,而是用新的程序替换了当前进程的正文,数据,堆和栈段。
5、system函数
#include <stdlib.h>
int system(const char *cmdstring);
描述:system执行一个命令字符串,原理是调用fork,exec和waitpid函数。