1、施行一个外部程序,什么时候必须用fork+execl而不能直接system() (http://www.myexception.cn/linux-unix/1341326.html)
1.1、system 是 fork/exec 的一个 wrapper, 灵活性不如 fork
1.2、你想不阻塞,手动回收子进程的时候 waitpid
system()会调用fork()产生子进程,由子进程来调用/bin/sh-c string来执行参数string字符串所代表的命令,此命令执行完后随即返回原调用的进程。在调用system()期间SIGCHLD 信号会被暂时搁置,SIGINT和SIGQUIT 信号则会被忽略。
看下system的实现,调用system后 父进程会阻塞在 waitpid上
int system(const char * cmdstring) { pid_t pid; int status; if(cmdstring == NULL) { return (1); //如果cmdstring为空,返回非零值,一般为1 } if((pid = fork())<0) { status = -1; //fork失败,返回-1 } else if(pid == 0) { execl("/bin/sh", "sh", "-c", cmdstring, (char *)0); _exit(127); // exec执行失败返回127,注意exec只在失败时才返回现在的进程,成功的话现在的进程就不存在啦~~ } else //父进程 { while(waitpid(pid, &status, 0) < 0) { if(errno != EINTR) { status = -1; //如果waitpid被信号中断,则返回-1 break; } } } return status; //如果waitpid成功,则返回子进程的返回状态 }
2、修改进程名
2.1、unix/linux 给fork()出的子进程改名、重命名(http://blog.csdn.net/u010606602/article/details/52193449)
问题描述:
在一个进程中,负责监听数据,然后派发给fork出来的子进程处理,系统需要为了显示、及后面kill时可以只杀对应子进程(一开始没对子进程id进行保存,也不想这么做),要对fork出来的进程重新命名。
案例:
父进程:AbmServer -HB -f1
子进程1:AbmServerSub -HB -l1
子进程2:AbmServerSub -HB -l2
子进程3:AbmServerSub -HB -l3
要在fork之后得到以上的效果。
解决:
方法有两种:
1、修改main
函数的参数argv;
在父进程启动时备份一份这个参数(指针备份,还是指向运行参数地址,后面改变才会生效),然后再fork
中对这个参数直接重名即可。
2、借助函数prctl
进程重命名代码:
prctl(PR_SET_NAME, “process_name”, NULL, NULL, NULL);
第一个参数是操作类型,指定PR_SET_NAME,即设置进程名
第二个参数是进程名字符串,长度至多16字节.
2.2、修改通过fork生成的进程名(http://blog.csdn.net/marike1314/article/details/9332675)
#include <sys/prctl.h> int main(char argc[],int argv) { unsigned int i = 0; unsigned int pid1,pid2; if(0 == fork()){ prctl(PR_SET_NAME,"Child",NULL,NULL,NULL); for(;;){ for(i=0;i<100000;i++); pid1= getpid; printf("This is the child process,process id is %d",pid1); } }else{ prctl(PR_SET_NAME,"Child",NULL,NULL,NULL); for(;;){ for(i=0;i<100000;i++); pid1= getpid; printf("This is the child process,process id is %d",pid1); } } return 0; }
2.3、ZC: 我的测试代码
ZC: 测试结果:
(1)、修改argv[0]内容的方式 : 感觉上比较怪异,非正统,没有必要的话,尽量避免该种方式
(2)、“prctl(PR_SET_NAME, ?, ?, ?, ?);” : 个人感觉,这是正统的方式
#include <stdio.h> #include <string.h> #include <sys/types.h> #include <sys/prctl.h> #include <unistd.h> int main(int _argc, char* _argv[]) { unsigned int iPID01=0, iPID02 = 0; unsigned int iRtn = 0; char* pcArgv0 = _argv[0]; char* pcSubProcessName = "ForkSub01"; iRtn = fork(); if (0 == iRtn) { //memcpy(pcArgv0, pcSubProcessName, strlen(pcSubProcessName)); //pcArgv0[strlen(pcSubProcessName)] = '\0'; //pcArgv0[strlen(pcSubProcessName)+1] = '\0'; printf("Sub process .\n"); prctl(PR_SET_NAME, "ForkTest01_Sub", NULL, NULL, NULL); while (1) { iPID01 = getpid(); printf("This is the sub process, process id is : %d\n", iPID01); usleep(1000 * 1000); } } else { while (1) { iPID02 = getpid(); printf("This is the parent process, process id is : %d, sub process id is : %d\n", iPID02, iRtn); usleep(1000 * 1000); } } return 0; }
3、
4、
5、