linux 中 execv, fork, wait 及 waitpid 的用法
来源:互联网 发布:费洛蒙 牌子 知乎 编辑:程序博客网 时间:2024/05/22 00:10
1. execv()
1.1函数原型
#include <unistd.h>
int execv(const char *progname, char *const argv[]);
1.2 用法介绍
execv会停止执行当前的进程,并且以progname应用进程替换被停止执行的进程,进程ID没有改变。
progname: 被执行的应用程序。
argv: 传递给应用程序的参数列表, 注意这个数组的第一个参数应该是应用程序名字本身(即argv[0] = progname),并且最后一个参数应该为NULL,不能将多个参数合并为一个参数放入数组。
1.3 返回值
如果应用程序正常执行完毕,那么execv是永远不会返回的;当execv在调用进程中返回时,那么这个应用程序应该出错了(可能是程序本身没找到,权限不够等), 此时它的返回值应该是-1,具体的错误代码可以通过全局变量errno查看,还可以通过stderr得到具体的错误描述字符串。
#include <stdlib.h>#include <stdio.h>#include <unistd.h>#include <errno.h>#include <string.h>main(void){ pid_t pid = fork(); if( pid == 0 ) // this is the child process { const char *arg1 = "/bin/sh"; const char *arg2 = "-c"; const char *arg3 = "mkdir mydir"; const char *arg4 = NULL; const char *arg[] = {arg1, arg2, arg3, arg4}; execv(arg[0], (char* const*)&arg[0]); // the program should not reach here, or it means error occurs during execute the ls command. printf("command ls is not found, error code: %d(%s)\n", errno, strerror(errno)); }}
2. wait(等待子进程中断或结束)
2.1 函数原型
#include<sys/types.h>
#include<sys/wait.h>
pid_t wait (int * status);
2.2 函数说明:
(1) wait()会暂时停止目前进程的执行,直到有信号来到或子进程结束。如果在调用 wait()时子进程已经结束,则 wait()会立即返回子进程结束状态值。
(2) 子进程的结束状态值会由参数 status 返回,而子进程的进程识别码也会一起返回。状态值status的具体含义请参考 waitpid()。
(3) 如果执行成功则返回子进程PID,如果有错误发生则返回返回值-1,失败原因存于 errno 中。
(4) 如果不需要status状态值,则参数 status 可以设成 NULL。
3. waitpid(等待子进程中断或结束)
3.1 函数原型
#include<sys/types.h>
#include<sys/wait.h>
pid_t waitpid(pid_t pid, int * status, int options);
3.2 函数说明:
(1) waitpid()会暂时停止目前进程的执行,直到有信号来到或子进程结束。如果在调用waitpid()时子进程已经结束,则 waitpid()会立即返回子进程结束状态值。
(2) 子进程的结束状态值会由参数 status 返回,而子进程的进程识别码也会一快返回。
(3) 如果执行成功则返回子进程PID,如果有错误发生则返回返回值-1,失败原因存于 errno 中。
(4) 如果不在意结束状态值,则参数 status 可以设成 NULL。
(5) 参数 pid 为欲等待的子进程识别码,其他数值意义如下:
pid<-1 等待进程组识别码为 pid 绝对值的任何子进程。
pid=-1 等待任何子进程,相当于 wait()。
pid=0 等待进程组识别码与目前进程相同的任何子进程。
pid>0 等待任何子进程识别码为 pid 的子进程。
(6) 参数 option 可以为 0 或下面的 OR 组合:
WNOHANG 如果没有任何已经结束的子进程则马上返回, 不予以等待。
WUNTRACED 如果子进程进入暂停执行情况则马上返回,但结束状态不予以理会。
(7) 子进程的结束状态返回后存于 status, 底下有几个宏可判别结束情况:
- //Linux <sys/wait.h>
- #define WEXITSTATUS(s) (((s) & 0xff00) >> 8)
- #define WCOREDUMP(s) ((s) & 0x80)
- #define WTERMSIG(s) ((s) & 0x7f)
- #define WSTOPSIG(s) WEXITSTATUS(s)
- #define WIFEXITED(s) (WTERMSIG(s) == 0)
- #define WIFSTOPPED(s) (WTERMSIG(s) == 0x7f)
- #define WIFSIGNALED(s) (WTERMSIG((s)+1) >= 2)
a. WIFEXITED(status) 如果子进程正常结束则为true。exit(0), exit(-1), 都是正常结束。例如 exit(0), status = 0; exit(-1), status = 0xFF00; exit(-10), status = 0xF600
b. WEXITSTATUS(status) 取得子进程 exit()返回的结束代码,一般会先用 WIFEXITED 来判断是否正常结束才能使用此宏。
c. WIFSIGNALED(status) 如果子进程是因为信号而结束则此宏值为真。
d. WTERMSIG(status) 取得子进程因信号而中止的信号代码,一般会先用 WIFSIGNALED 来判断后才使用此宏。
e. WIFSTOPPED(status) 如果子进程处于暂停执行情况则此宏值为真。一般只有使用 WUNTRACED 时才会有此情况。
f. WSTOPSIG(status) 取得引发子进程暂停的信号代码,一般会先用 WIFSTOPPED 来判断后才使用此宏。
3.3 调用举例
int main() { int cpid = fork(); if (cpid < 0) { return -1; } else if (cpid == 0) { char *arg1 = "system/bin/sh"; char *arg2 = "-c"; char *arg3 = "mkdir mydir"; char *arg4 = NULL; char *arg[] = {arg1, arg2, arg3, arg4}; execv(arg[0], &arg[0]); printf("########## exec_command(): error code: %d(%s) ##########", errno, strerror(errno)); exit(-1); } else { int status = -1; int count = 0; while(1) { //int ret = waitpid(cpid, &status, 0); 如果子进程不结束会一直死等 int ret = waitpid(cpid, &status, WNOHANG);//WNOHANG 配合while 循环可以实现超时机制 if (ret) { if (WIFEXITED(status)) { //子进程正常结束: exit(任意值无论正负), execv()执行结束没有崩溃 //1. execv()执行成功结束: status = 0 //2. execv()执行结束,但可能没有执行成功,内部调用了exit(-1): status = 0xFF00 //3. 子进程直接调用 exit(-1): status = 0xFF00 //4. 子进程直接调用 exit(-10): status = 0xF600 if (WEXITSTATUS(status) == 0xFF) { //TODO } else if (WEXITSTATUS(status) == 0xF6) { //TODO } else { //TODO } } else { //子进程非正常结束:子进程执行execv()发生崩溃,子进程是因为信号signal而结束 //TODO } break; } if (++count >= 60) { //timeout = 60s break; } sleep(1); } } return 0; }
0 0
- linux 中 execv, fork, wait 及 waitpid 的用法
- linux 中 execv, fork, wait 及 waitpid 的用法
- linux中waitpid及wait的用法
- linux中waitpid及wait的用法
- fork、execv 及 waitpid 的例子代码
- linux 下的 wait及waitpid种种
- linux中wait与waitpid的差别
- linux中wait与waitpid的差别
- linux中wait与waitpid的差别
- linux中wait与waitpid的差别
- Linux进程相关,fork,wait,waitpid,WIFEXITED
- linux系统调用之-fork、wait、waitpid
- linux waitpid/wait函数用法
- linux waitpid/wait函数用法
- wait和waitpid的用法
- Linux中的SIGCHLD及wait,waitpid的使用
- Linux/Unix之wait()和waitpid()用法
- linux进程(fork/vfork)与wait/waitpid
- iOS超全开源框架、项目和学习资料汇总
- CSS入门教程(二)
- 人生没有下辈子
- 自定义cell
- jQuery--Ajax
- linux 中 execv, fork, wait 及 waitpid 的用法
- long,double高低位,非线程安全
- tableView的底层实现
- centos 手动安装数据库
- [iOS]Xcode常用快捷键
- 基于XML,以POST方式,完成省份-城市二级下拉联动
- layoutIfNeeded
- 打造安卓流式布局
- 2254 字母旋转方程