zoukankan      html  css  js  c++  java
  • 信息安全系统设计基础第十二周学习总结(代码实践)

    exec1

     #include <stdio.h>
     #include <unistd.h>
    
     int main()
     {
        char    *arglist[3];
    
        arglist[0] = "ls"; 
        arglist[1] = "-l";
        arglist[2] = 0 ;//NULL
        printf("* * * About to exec ls -l
    ");
        execvp( "ls" , arglist );
        printf("* * * ls is done. bye");
    
        return 0;
     }
    

    其中:

    execvp(执行文件)

    1. 相关函数:
      fork,execl,execle,execlp,execv,execve

    2. 表头文件:
      #include<unistd.h>

    3. 定义函数:

        int execvp(const char *file ,char * const argv []);
                           返回:如果执行成功则函数不会返回,执行失败则直接返回-1,失败原因存于errno中。
      
    4. 函数说明:

      execvp()会从PATH 环境变量所指的目录中查找符合参数file 的文件名,找到后便执行该文件,然后将第二个参数argv传给该欲执行的文件。

    运行结果:

    exec2

    #include <stdio.h>
    #include <unistd.h>
    
    int main()
    {
        char	*arglist[3];
    	arglist[0] = "ls";
    	arglist[1] = "-l";
        arglist[2] = 0 ;
        printf("* * * About to exec ls -l
    ");
        execvp( arglist[0] , arglist );
        printf("* * * ls is done. bye
    ");
    }
    

    exec2与exec1的不同是exevp中第一个参数不一样,exec1是ls,exec2是arglist[0]。

    运行结果:

    exec3

    #include <stdio.h>
    #include <unistd.h>
    
    int main()
    {
        char    *arglist[3];
        char*myenv[3];
        myenv[0] = "PATH=:/bin:";
        myenv[1] = NULL;
    
        arglist[0] = "ls";
        arglist[1] = "-l";
        arglist[2] = 0 ;
        printf("* * * About to exec ls -l
    ");
    
        execlp("ls", "ls", "-l", NULL);
        printf("* * * ls is done. bye
    ");
    }
    

    其中:

    execlp()函数

    属于exec()函数族(exec()族函数用一个新的进程映像替换当前进程映像)它是execve(2)函数的前端

    1. 相关函数:fork,execl,execle,execv,execve,execvp

    2. 头文件:#include<unistd.h>

    3. 定义函数:

       int execlp(const char * file,const char * arg,....);
                       返回:如果执行成功则函数不会返回,执行失败则直接返回-1,失败原因存于errno 中。
      
    4. 函数说明:

      execlp()会从PATH 环境变量所指的目录中查找符合参数file的文件名,找到后便执行该文件,然后将第二个以后的参数当做该文件的argv[0]、argv[1]……,最后一个参数必须用空指针(NULL)作结束。如果用常数0来表示一个空指针,则必须将它强制转换为一个字符指针,否则将它解释为整形参数,如果一个整形数的长度与char * 的长度不同,那么exec函数的实际参数就将出错。如果函数调用成功,进程自己的执行代码就会变成加载程序的代码,execlp()后边的代码也就不会执行了.

    运行结果:

    这个代码指定了环境变量,然后依然执行了ls -l指令,成功后没有返回,所以最后一句话不会输出。运行结果同exec1.

    forkdemo1

    #include    <stdio.h>
    #include<sys/types.h>
    #include<unistd.h>
    int main()
    {
        int ret_from_fork, mypid;
        mypid = getpid();              
        printf("Before: my pid is %d
    ", mypid);
        ret_from_fork = fork();
        sleep(1);
        printf("After: my pid is %d, fork() said %d
    ",
              getpid(), ret_from_fork);
    
        return 0;
    }
    

    运行结果:

    代码理解:先打印进程pid,然后fork生成子进程,休眠一秒后再次打印进程id,这时父进程打印子进程pid,子进程返回0.

    forkdemo2

    #include <stdio.h> 
    #include <unistd.h>
    
    int main()
    {
        printf("before:my pid is %d
    ", getpid() );
        fork();
        fork();
        printf("aftre:my pid is %d
    ", getpid() );
    
        return 0;
    }
    

    调用两次fork,产生四个子进程,所以会打印四个aftre输出。

    运行结果:

    forkdemo3

    #include    <stdio.h>
    #include    <stdlib.h>
    #include    <unistd.h>
    
    int main()
    {
        int fork_rv;
    
        printf("Before: my pid is %d
    ", getpid());
    
        fork_rv = fork();       /* create new process   */
    
        if ( fork_rv == -1 )        /* check for error  */
            perror("fork");
        else if ( fork_rv == 0 ){ 
            printf("I am the child.  my pid=%d
    ", getpid());
    
            exit(0);
        }
        else{
            printf("I am the parent. my child is %d
    ", fork_rv);
            exit(0);
        }
    
        return 0;
    }
    

    运行结果:

    forkdemo4

    #include    <stdio.h>
    #include    <stdlib.h>
    #include    <unistd.h>
    
    int main()
    {
        int fork_rv;
    
        printf("Before: my pid is %d
    ", getpid());
    
        fork_rv = fork();       /* create new process   */
    
        if ( fork_rv == -1 )        /* check for error  */
            perror("fork");
    
        else if ( fork_rv == 0 ){ 
            printf("I am the child.  my pid=%d
    ", getpid());
            printf("parent pid= %d, my pid=%d
    ", getppid(), getpid());
            exit(0);
        }
        else{
            printf("I am the parent. my child is %d
    ", fork_rv);
            sleep(10);
            exit(0);
        }
        return 0;
    }
    

    运行结果如下:

    forkgdb

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    
    int  gi=0;
    int main()
    {
        int li=0;
        static int si=0;
        int i=0;
    
        pid_t pid = fork();
        if(pid == -1){
            exit(-1);
        }
        else if(pid == 0){
            for(i=0; i<5; i++){
                printf("child li:%d
    ", li++);
                sleep(1);
                printf("child gi:%d
    ", gi++);
                printf("child si:%d
    ", si++);
            }
            exit(0);
          
        }
        else{
            for(i=0; i<5; i++){
                printf("parent li:%d
    ", li++);
                printf("parent gi:%d
    ", gi++);
                sleep(1);
                printf("parent si:%d
    ", si++);
            }
            exit(0);    
    
        }
        return 0;
    }
    

    运行结果:


    父进程打印先打印两句parent,休眠一秒,再打印一句parent,子进程先打印一句child,休眠一秒,再打印两句child。两个线程并发执行,在一个线程休眠的一秒,另一个线程执行,并且线程之间相互独立互不干扰。

    testbuf1:

    #include <stdio.h>
    #include <stdlib.h>
    int main()
    {
        printf("hello");
        fflush(stdout);
        while(1);
    }
    

    testbuf2

    #include <stdio.h>
    int main()
    {
        printf("hello
    ");
        while(1);
    }
    

    fflush(stdout):

    在printf()后使用fflush(stdout)的作用是立刻将要输出的内容输出。

    当使用printf()函数后,系统将内容存入输出缓冲区,等到时间片轮转到系统的输出程序时,将其输出。 使用fflush(out)后,立刻清空输出缓冲区,并把缓冲区内容输出。

    testbuf3

    #include <stdio.h>
    
    int main()
    {
        fprintf(stdout, "1234", 5);
        fprintf(stderr, "abcd", 4);
    }
    

    将内容格式化输出到标准错误、输出流中。

    stderr -- 标准错误输出设备  
    stdout -- 标准输出设备 (printf(".."))    
    

    两者默认向屏幕输出。 但如果用转向标准输出到磁盘文件,则可看出两者区别。stdout输出到磁盘文件,stderr在屏幕。

    运行结果:

    waitdemo1

    #include    <stdio.h>
    #include    <stdlib.h>
    #include    <sys/types.h>
    #include    <sys/wait.h>
    #include    <unistd.h>
    
    #define DELAY   4
    
    void child_code(int delay)
    {
        printf("child %d here. will sleep for %d seconds
    ", getpid(), delay);
        sleep(delay);
        printf("child done. about to exit
    ");
        exit(17);
    }
    
    void parent_code(int childpid)
    {
        int wait_rv=0;      /* return value from wait() */
        wait_rv = wait(NULL);
        printf("done waiting for %d. Wait returned: %d
    ", 
                childpid, wait_rv);
    }
    int main()
    {
        int  newpid;
        printf("before: mypid is %d
    ", getpid());
        if ( (newpid = fork()) == -1 )
            perror("fork");
        else if ( newpid == 0 )
            child_code(DELAY);
        else
            parent_code(newpid);
    
        return 0;
    }
    

    如果有子进程,则终止子进程,成功返回子进程pid。

    运行结果:

    waitdemo2

    #include    <stdio.h>
    #include    <stdlib.h>
    #include    <sys/types.h>
    #include    <sys/wait.h>
    #include    <unistd.h>
    
    #define DELAY   10
    
    void child_code(int delay)
    {
        printf("child %d here. will sleep for %d seconds
    ", getpid(), delay);
        sleep(delay);
        printf("child done. about to exit
    ");
        exit(27);
    }
    
    void parent_code(int childpid)
    {
        int wait_rv;    
        int child_status;
        int high_8, low_7, bit_7;
    
        wait_rv = wait(&child_status);
        printf("done waiting for %d. Wait returned: %d
    ", childpid, wait_rv);
    
        high_8 = child_status >> 8;     /* 1111 1111 0000 0000 */
        low_7  = child_status & 0x7F;   /* 0000 0000 0111 1111 */
        bit_7  = child_status & 0x80;   /* 0000 0000 1000 0000 */
        printf("status: exit=%d, sig=%d, core=%d
    ", high_8, low_7, bit_7);
    }
    
    int main()
    {
        int  newpid;
    
        printf("before: mypid is %d
    ", getpid());
    
        if ( (newpid = fork()) == -1 )
            perror("fork");
        else if ( newpid == 0 )
            child_code(DELAY);
        else
            parent_code(newpid);
    }
    

    运行结果:

    遇到的问题:

    在testbuf1和testbuf2运行的不太懂。testbuf1运行出来打印一个hello,testbuf2运行出来也是打印一个hello。我把testbuf1中的"fflush(stdout);"标识为注释后,则什么都打印不出来。是为什么?

  • 相关阅读:
    测试
    201920201 20199320《Linux内核原理与分析》第四周作业
    201920201 20199320《Linux内核原理与分析》第六周作业
    201920201 20199320《Linux内核原理与分析》第五周作业
    201920201 20199320《Linux内核原理与分析》第七周作业
    201920201 20199320《Linux内核原理与分析》第一周作业
    201920201 20199320《Linux内核原理与分析》第八周作业
    ASP.NET MVC3 Custom FormAuthorize
    堆排序练习题
    面试题:4亿里有多少个1(11算2个)。
  • 原文地址:https://www.cnblogs.com/lhc-java/p/5005330.html
Copyright © 2011-2022 走看看