帮助手册:man 3 getenv
包含头文件:`#include
函数原型:
char *getenv(const char *name);
| 参数 | 说明 |
|---|---|
| name | 环境变量 |
| return | 成功:环境变量的值 失败:NULL |
帮助手册:man 3 setenv
包含头文件:`#include
函数原型:
int unsetenv(const char *name);
| 参数 | 说明 |
|---|---|
| name | 环境变量名 |
| value | 变量值 |
| overwrite | 当环境变量存在时 0:不重写 非0:重写 |
| return | 成功:0 失败:-1,并设置errno |
帮助手册:man 3 unsetenv
包含头文件:`#include
函数原型:
char *getenv(const char *name);
| 参数 | 说明 |
|---|---|
| name | 环境变量名 |
| return | 成功:0 失败:-1,并设置errno |
帮助手册:man 2 fork
包含头文件:#include
#include 函数原型:
pid_t fork(void);刚fork()后:
父子进程相同处:
– 全局变量,data, text, 栈,堆,环境变量,用户ID,宿主目录,进程工作目录,信号处理方式…父子进程不相同处:
– 进程ID, fork返回值,父进程ID, 进程运行时间,闹钟(定时器),未决信号集注:父子进程间数据读时共享,写时复制,父子进程不共享全局变量
| 参数 | 说明 |
|---|---|
| return | 成功:子进程:0;父进程:子进程PID 失败:-1,并设置errno |
帮助手册:man 2 getpid
包含头文件:#include
#include 函数原型:
pid_t getpid(void)
| 参数 | 说明 |
|---|---|
| return | 返回当前进程的PID |
帮助手册:man 2 getppid
包含头文件:#include
#include 函数原型:
pid_t getppid(void)
| 参数 | 说明 |
|---|---|
| return | 返回父进程的PID |
示例:
#include3.5 执行一个文件 3.5.1 execl()#include int main(int argc, char* argv[]) { printf("Begin...n"); pid_t pid = fork(); if(pid < 0) { perror("fork error:"); return -1; } if(pid == 0) printf("This is child process, PID = %d, PPID = %dn", getpid(), getppid()); if(pid > 0) printf("This is parent process, pid = %d, PID = %d, PPID = %dn", pid, getpid(), getppid()); printf("End...n"); return 0; }
帮助手册:man 2 execl
包含头文件:#include
函数原型:
int execl(const char *pathname, const char *arg, ... );
| 参数 | 说明 |
|---|---|
| pathname | 可执行文件路径 |
| arg | 参数(注:arg[0]需要用可执行文件占位,最后需要用NULL标识) |
| return | 成功:不返回 失败:-1,并设置errno |
帮助手册:man 2 execlp
包含头文件:#include
函数原型:
int execlp(const char *file, const char *arg, ... );函数说明:
执行程序时,使用PATH环境变量,执行的程序可以不用加路径
| 参数 | 说明 |
|---|---|
| file | 可执行文件路径 |
| arg | 参数(注:arg[0]需要用可执行文件占位,最后需要用NULL标识) |
| return | 成功:不返回 失败:-1,并设置errno |
注:execl()和execlp()会将原来的代码断进行替换
#include3.6 等待子进程中断或结束#include int main(int argc, char* argv[]) { execlp("ls", "ls", "-l", NULL); perror("execlp error:"); return 0; }
孤儿进程:父进程运行结束,子进程被init进程领养。僵尸进程:子进程运行结束,父进程没有回收子进程资源(PCB)
孤儿进程示例:
#include#include #include int main(int argc, char* argv[]) { pid_t pid = fork(); if(pid == 0) { while(1) { printf("child process...ppid=%dn", getppid()); sleep(1); } } if(pid > 0) { sleep(3); printf("The parent process is finished...n"); } return 0; }
僵尸进程示例:
#include3.6.1wait()#include #include int main(int argc, char* argv[]) { pid_t pid = fork(); if(pid == 0) { sleep(1); printf("The child process is finished...n"); } if(pid > 0) { while(1) { printf("parent process...n"); sleep(1); } } return 0; }
帮助手册:man 2 wait
包含头文件:#include
#include 函数原型:
pid_t wait(int *wstatus);函数说明:
wait()会暂时停止目前进程的执行,直到有信号来到或子进程结束。如果在调用wait()时子进程已经结束,则wait()会立即返回子进程结束状态值,并回收子进程的PCB。子进程的结束状态值会由参数wstatus返回,而子进程的进程识别码也会一块返回。如果不在意结束状态值,则参数wstatus可以设为NULL。子进程的结束状态值参考waitpid()。
| 参数 | 说明 |
|---|---|
| wstatus | 传出参数(子进程的死亡原因) |
| return | 成功:子进程PID 失败:-1,并设置errno |
子进程的死亡原因:
示例:
#include3.6.2 waitpid()#include #include #include int main(int argc, char* argv[]) { pid_t pid = fork(); if(pid == 0) { sleep(2); printf("The child process is finished...n"); } if(pid > 0) { printf("wait...n"); pid_t wpid = wait(NULL); printf("The child process was dead. wpid = %d, pid = %dn", wpid, pid); while(1) sleep(1); } return 0; }
帮助手册:man 2 waitpid
包含头文件:#include
#include 函数原型:
pid_t waitpid(pid_t pid, int *wstatus, int options);
| 参数 | 说明 |
|---|---|
| pid | pid<-1:等待进程组识别码为pid绝对值的任何子进程 pid=-1:等待任何子进程,相当于wait() pid=0:等待进程组识别码与目前进程相同的任何子进程 pid>0:等待任何子进程识别码为pid的子进程 |
| options | NULL:与wait()相同,一会阻塞 WNOHANG:如果没有子进程存在立即返回 WUNTRACED:如果子进程进入暂停状态立马返回,但结束状态不予理会 WCONTINUED:如果通过SIGCONT恢复了停止的子进程,也返回 |
| return | 成功:子进程PID(如果设置了WNOHANG,如果没有子进程退出返回0) 失败:-1,并设置errno |
如果wstatus不为NULL,wait()和waitpid()将状态信息存储在*wstatus中。可以使用以下宏检查此整数:
| 宏 | 说明 |
|---|---|
| WIFEXITED(wstatus) | 如果子进程正常退出放回真 |
| WEXITSTATUS(wstatus) | 返回子进程的退出状态(注:WIFEXITED返回真可以使用) |
| WIFSIGNALED(wstatus) | 如果子进程被一个信号杀死返回真 |
| WTERMSIG(wstatus) | 返回杀死子进程的信号(注:WIFSIGNALED返回真可以使用) |
| WCOREDUMP(wstatus) | 如果子进程核转储返回真(注:WIFSIGNALED返回真可以使用) |
| WIFSTOPPED(wstatus) | 如果子进程处于暂停状态返回真(注:WIFSIGNALED返回真可以使用) |
| WSTOPSIG(wstatus) | 返回引发子进程暂停的信号代码(注:WIFSIGNALED返回真可以使用) |
| WIFConTINUED(wstatus) | 如果子进程回复继续运行返回真 |
示例:
#include#include #include #include int main(int argc, char* argv[]) { pid_t pid = fork(); if(pid == 0) { printf("tChild dead.n"); sleep(2); return 1; } if(pid > 0) { printf("wait for child die!n"); int status; pid_t wpid = wait(NULL); printf("wait ok, wpid = %d, pid = %dn", wpid, pid); if(WIFEXITED(status)) { printf("child exit with %dn", WEXITSTATUS(status)); } if(WIFSIGNALED(status)) { printf("child killed by %dn", WTERMSIG(status)); } while(1) { sleep(1); } } return 0; }
#include#include #include #include int main(int argc, char* argv[]) { pid_t pid = fork(); if(pid == 0) { printf("tChild dead. pid = %dn", getpid()); sleep(2); return 1; } if(pid > 0) { printf("wait for child die!n"); int ret; while((ret = waitpid(-1, NULL, WNOHANG)) == 0); printf("ret = %dn", ret); while(1) { sleep(1); } } return 0; }



