dup重定向匿名管道父进程子进程的一些坑包含execvp调用ffmepg
来源:互联网 发布:iphone检测软件 编辑:程序博客网 时间:2024/06/05 21:01
dup重定向匿名管道父进程子进程的一些坑包含execvp调用ffmepg
本文说明再用dup做重定向的时候遇到的一些坑做一些总结。
1:FFMPEG的所有输出信息,都为错误输出流,用STDOUT_FILENO是捕获不到任何消息,必须用STDERR_FILENO,这里是个大坑;
2:子进程pid == 0 这一段代码走完返回后还会将主进程调用本函数之后的代码走一遍;
3:循环sleep要刷新fflush(stdout);才能在标准输出中输出到管道否则失败;
4:传入execvp的第二个参数argv类型为,char * execargv[LVSM_DEFAULT_STRING_LEN];当把前面的各个参数写入后,必须这样写execargv[pos] = NULL;否则失败,不能sprintf(execargv[pos],"%s",(char*)(0));或者,sprintf(execargv[pos],"%d",0);
5:代码中有匿名管道改成非阻塞的,否则read会卡住不返回。
下面是具体的代码对比看下:
//main.cpp
#include <unistd.h> #include <stdio.h> #include <sys/wait.h> #include <sys/prctl.h>#include <signal.h>#include <fcntl.h>#include <string.h>#include <memory.h>#include<stdlib.h>int child_processing_transcode(int pipe_id[2],int * pchild_pid, char *execpathname,char * execargv[]){int ret = 0;int pid = 0; //创建子进程的pidpid = fork(); //第一次返回就是子进程的pid*pchild_pid = pid; //拷贝子进程的pidif(pid< 0){ printf("error fork\n");*pchild_pid = -1;return -1;} else if(pid == 0) //子进程负责写 { prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0); //Linux下让父进程结束后,子进程自动结束close(pipe_id[0]); //关闭匿名管道读close(STDOUT_FILENO); //关闭标准输出close(STDERR_FILENO); //关闭标准错误输出dup2(pipe_id[1], STDOUT_FILENO); //将标准输出的输出重定向到匿名管道写中STDIN_FILENO == 0,STDOUT_FILENO == 1,STDERR_FILENO == 2;dup2(pipe_id[1], STDERR_FILENO); //FFMPEG的所有输出信息,都为错误输出流,用STDOUT_FILENO是捕获不到任何消息,必须用STDERR_FILENO,这里是个大坑;//char *argv[] = {(char *)"ls",(char *)"-l",(char *)"/etc",(char *)0}; //execvp("ls",argv);//printf ("Hello\n");//printf ("123\n");//printf ("ooppqq\n");//执行外挂的ffmpegexecvp(execpathname,execargv);//这有个大坑,子进程pid == 0 这一段代码走完返回后还会将主进程调用本函数之后的代码走一遍。//循环sleep要刷新fflush(stdout);才能在标准输出中输出到管道否则失败.exit(0); } else //父进程负责读 { int father_pid = getpid();printf("father_pid ;%d\n",father_pid);printf("*pchild_pid : %d\n",*pchild_pid); close(pipe_id[1]); //关闭匿名管道的写}return ret;}int main(){int ret = 0;int npipe_id[2] = {0}; //匿名管道,读npipe_id[0],写npipe_id[1] int nchild_pid = 0; //子进程pidint nreadlen = 0; //管道中读取的内存长度char sreadbuf[10240] = {0}; //管道中读取的内存if(pipe(npipe_id) < 0) {printf("error pipe\n");return 0;}//将读取fd设置成无阻塞int flag = fcntl(npipe_id[0],F_GETFL,0);flag |= O_NONBLOCK;if(fcntl(npipe_id[0],F_SETFL,flag) < 0){ perror("error fcntl(npipe_id[0],F_SETFL,flag)"); return 0;}//如果文件存在删除文件remove("out.flv");//转码 //ffmpeg -i 22.flv -acodec copy -vcodec h264 -s 352x288 -f flv out.flv//char execpathname[] = {"ffmpeg"};//char * execargv[] ={(char *)"ffmpeg",//(char *)"-i",(char *)"22.flv",//(char *)"-acodec", (char *)"copy", //(char *)"-vcodec", (char *)"h264", //(char *)"-s", (char *)"352x288" ,(char *)"-f" ,(char *)"flv", //(char *)"out.flv",0};//遮标char execpathname[] = {"cover_standard"};char * execargv[] ={(char *)"cover_standard",0};ret = child_processing_transcode(npipe_id,&nchild_pid,execpathname,execargv);printf("nchild_pid : %d\n",nchild_pid);usleep(1000* 1000);//第一次调用waitpid时:此时尚未有子进程,所以waitpid出错,返回-1;//第二次调用waitpid时:此时有子进程,但子进程尚未结束,由于waitpid设置为非阻塞的,所以waitpid返回0;//第三次调用waitpid时:此时有子进程,所以waitpid返回子进程id;int stat = 0;int wpid = waitpid(nchild_pid, &stat, WNOHANG); //pid=-1 等待任何子进程,相当于 wait()。 //设置成WNOHANG非阻塞父进程状态printf("first-pchild_pid: %d\n", wpid); for (;;){nreadlen = read(npipe_id[0],sreadbuf,10240); if (nreadlen > 0){printf( "*********************************[nreadlen] : [%d] %s\n",nreadlen,sreadbuf); }memset(sreadbuf,0,10240);usleep(1000 * 1000);wpid = waitpid(-1, &stat, WNOHANG); //pid=-1 等待任何子进程,相当于 wait()。 //设置成WNOHANG非阻塞父进程状态printf("second-pchild_pid: %d\n", wpid); //printf("getpid : %d\n",getpid());}//如果子进程执行完关闭close( npipe_id[0] ); close( npipe_id[1] ); //杀死子进程kill(nchild_pid, SIGKILL); return 1;}
//cover_standard.cpp
#include <stdio.h>#include <unistd.h> int main(){int ret = 0;for (int i = 0; i <100; i++){printf("*****************cover_standard i : %d\n",i);usleep(1000*1000);//循环sleep要刷新fflush(stdout);才能在标准输出中输出到管道否则失败.fflush(stdout);}return 1;}
如有错误请指正:
交流请加QQ群:62054820
QQ:379969650.
阅读全文
0 0
- dup重定向匿名管道父进程子进程的一些坑包含execvp调用ffmepg
- 重定向dup、管道 进程间通信
- 重定向dup、管道 进程间通信
- 用无名管道重定向子进程的输入输出
- 匿名管道与子进程
- 管道重定向与进程间通信
- VC使用管道重定向进程输入输出
- Linux c 匿名管道实例—创建两个子进程与父进程进行管道通信
- 用途文件重定向子进程的输入输出
- 重定向子进程控制台程序的输入输出
- 匿名管道 的 管道复制(dup)
- 进程通信-匿名管道
- 进程通信 - 匿名管道
- 重定向子进程输出到文件
- 重定向子进程标准输入输出
- 匿名管道--进程间的通信
- 匿名管道在兄弟进程的应用
- C#重定向 进程调用 WinForm多线程
- 节点的类型
- CloudFoundry + OpenStack: Your Own Platform
- 输入子系统代码测试
- Socket编程
- Python的包管理工具pip的安装与使用
- dup重定向匿名管道父进程子进程的一些坑包含execvp调用ffmepg
- linux启动过程简介
- 在RedHat/CentOS中安装Mercurial(HG)
- 了解weight属性
- 微信文章分享自定义标题,简介和浓缩图
- 办公小技巧:怎么在PDF文件中添加页码
- Swing程序最佳架构设计—以业务对象为中心的MVC模式
- Oracle11g数据库 安装、卸载
- InfiniBand技术和协议架构分析