子进程01__资料

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、

 

posted @ 2016-10-12 08:25  LinuxCode  阅读(313)  评论(0编辑  收藏  举报