美文网首页
ostep-进程API

ostep-进程API

作者: 富贵山庄王动 | 来源:发表于2017-03-12 02:25 被阅读0次

    也可以称为系统调用。

    fork

    在unix中,创建新的进程可以使用fork。

    #include "syscalls.h"
    
    int main(int argc,char *argv[])
    {
        printf("hello,world (pid:%ld)\n",(long)getpid());
        long rc = fork();
        if(rc < 0)
        {
            fprintf(stderr,"forl failed\n");
            exit(1);
        } else if(rc == 0){
            printf("hello,I am child(pid:%ld)->(forkReturn:%ld)\n",(long)getpid(),rc);
        } else{
            printf("hello,I am parent(pid:%ld)->(forkReturn:%ld)\n",(long)getpid(),rc);
        }
    
        return 0;
    }
    

    输出就像这样:

    hello,world (pid:28244)
    hello,I am parent(pid:28244)->(forkReturn:28245)
    hello,I am child(pid:28245)->(forkReturn:0)
    

    关于fork创建的子进程,有几点需要知道。首先,子进程几乎是父进程的一个精确的拷贝,就是二者几乎完全一样。所以,子进程不需要从main开始运行。
    子进程有自己的私有PC,私有地址空间,自己的寄存器等等。当父进程收到子进程的PID时,子进程得到一个0的返回值。这个返回值是指fork的返回值。
    也就是说,fork返回给父进程子进程的PID,子进程得到的是0.具体可查看代码输出。
    以上代码的输出顺序是不固定的。书上说是不固定的,但是我试了好多次都是固定的,可能,虽然我也认同不是固定的。

    wait

    等待子进程完成。

    #include "syscalls.h"
    
    int main(int argc,char *argv[])
    {
        printf("hello,world (pid:%ld)\n",(long)getpid());
        long rc = fork();
        if(rc < 0)
        {
            fprintf(stderr,"forl failed\n");
            exit(1);
        } else if(rc == 0){
            printf("hello,I am child(pid:%ld)->(forkReturn:%ld)\n",(long)getpid(),rc);
        } else{
            int wc = wait(NULL);
            printf("hello,I am parent(pid:%ld)->(forkReturn:%ld)->(waitReturn:%d)\n",(long)getpid(),rc,wc);
        }
    
        return 0;
    }
    

    输入如下:

    hello,world (pid:28906)
    hello,I am child(pid:28907)->(forkReturn:0)
    hello,I am parent(pid:28906)->(forkReturn:28907)->(waitReturn:28907)
    

    wait的返回值是子进程pid。
    输出顺序固定。

    exec

    这个系统调用是用来运行其他程序的,创建基于其他程序的进程。

    #include "syscalls.h"
    
    int main(int argc,char *argv[])
    {
        printf("hello,world (pid:%ld)\n",(long)getpid());
        long rc = fork();
        if(rc < 0)
        {
            fprintf(stderr,"forl failed\n");
            exit(1);
        } else if(rc == 0){
            char *myargs[3];
            myargs[0] = strdup("wc");
            myargs[1] = strdup("ostep_exec.c");
            myargs[2] = NULL;
    
            execvp(myargs[0],myargs);
    
            printf("this should not print out");
            printf("hello,I am child(pid:%ld)->(forkReturn:%ld)\n",(long)getpid(),rc);
        } else{
            int wc = wait(NULL);
            printf("hello,I am parent(pid:%ld)->(forkReturn:%ld)->(waitReturn:%d)\n",(long)getpid(),rc,wc);
        }
    
        return 0;
    }
    

    输出如下:

    hello,world (pid:29268)
     30  66 767 ostep_exec.c
    hello,I am parent(pid:29268)->(forkReturn:29269)->(waitReturn:29269)
    

    exec的调用重新初始化了地址空间,包括堆栈等。以及代码和静态数据。
    但是exec的pid和fork得到的pid是一样的。

    tips:调用fork部分的实例代码

    #include "syscalls.h"
    
    int main(int argc,char *argv[])
    {
        printf("hello,world (pid:%ld)\n",(long)getpid());
        long rc = fork();
        if(rc < 0)
        {
            fprintf(stderr,"forl failed\n");
            exit(1);
        } else if(rc == 0){
            char *myargs[3];
            myargs[0] = strdup("./process");
            myargs[1] = NULL;
            myargs[2] = NULL;
    
            execvp(myargs[0],myargs);
    
            printf("this should not print out");
            printf("hello,I am child(pid:%ld)->(forkReturn:%ld)\n",(long)getpid(),rc);
        } else{
            int wc = wait(NULL);
            printf("hello,I am parent(pid:%ld)->(forkReturn:%ld)->(waitReturn:%d)\n",(long)getpid(),rc,wc);
        }
    
        return 0;
    }
    

    相关文章

      网友评论

          本文标题:ostep-进程API

          本文链接:https://www.haomeiwen.com/subject/aoqtnttx.html