zoukankan      html  css  js  c++  java
  • 2017-2018-1 20155205 《信息安全系统设计基础》第六周学习总结

    2017-2018-1 20155205 《信息安全系统设计基础》第六周学习总结

    教材学习内容总结

    1.系统调用:进程控制

    • fork系统调用

      • 函数作用:创建一个子进程

      • 形式:pid_tfork(void);
        pid_t vfork(void);

      • 说明: 使用vfork创子进程时,不会进程父进程的上下文

      • 返回值:

      [返回值=-1]子进程创建失败

      [返回值=0]子进程创建成功

      [返回值>0]对父进程返回子进程PID

      测试代码:

    #include<stdio.h>
    #include<sys/stat.h>
    #include<unistd.h>
    int main() {
        pid_t id = fork();
        if (id < 0) {
            perror("子进程创建失败!");
        } else {
            if (id == 0) {
                printf("子进程工作:PID=%d,PPID=%d
    ", getpid(), getppid());
            }else
            {
                printf("父进程工作:PID=%d,PPID=%d,子进程PID=%d
    ", getpid(), getppid(),id);
                sleep(5);
            }
        }
    }
    

    测试结果:

    • exit系统调用

      • 函数作用:终止发出调用的进程

      • 形式:voidexit(int status);

      • 说明

        1. exit返回信息可由wait系统函数获得
        2. 如果父进程先退出子进程的关系被转到init进程下

      测试代码:

    #include<stdio.h>
    #include<sys/stat.h>
    #include<unistd.h>
    #include<stdlib.h>
    int main() {
        pid_t id = fork();
        if (id < 0) {
            perror("子进程创建失败!");
        } else {
            if (id == 0) {
                printf("子进程工作:PID=%d,PPID=%d
    ", getpid(), getppid());
                sleep(20);
                printf("此时子进程:PID=%d,PPID=%d
    ", getpid(), getppid());
            }else
            {
                printf("父进程工作:PID=%d,PPID=%d,子进程PID=%d
    ", getpid(), getppid(),id);
                sleep(5);
                exit(3);
            }
        }
        return 0;
    }
    

    测试结果:

    • exec系统调用

      • 函数作用:以新进程代替原有进程,但PID保持不变

    测试代码1:

    #include<stdio.h>
    #include<unistd.h>
    
    int main()
    {
    printf("这是第一个进程PID=%d
    ",getpid());
    execv("exec2",NULL);
    printf("asa");
    return 0;
    }
    

    测试代码2:

    #include<stdio.h>
    #include<unistd.h>
    
    int main()
    {
    printf("这是第二个进程PID=%d
    ",getpid());
    }
    

    测试结果:

    • wait系统调用

      • 函数作用:父进程与子进程同步,父进程调用后,进入睡眠状态,直到子进程结束或者父进程在被其他进程终止。

      • 形式:pid_twait(int *status) pid_t waitpid(pid_t pid ,int *status,int option)

      • 参数:status:exit是设置的代码
        pid:进程号
        option: WNOHANG|WUNTRACED

        WNOHANG:,即使没有子进程退出,它也会立即返回,不会像wait那样永远等下去.
        WUNTRACED:子进程进入暂停则马上返回,但结束状态不予以理会.

      • 返回值:如果成功等待子进程结束,则返回子进程PID。后者为-1

    • setenv函数和unsetenv函数

      • 命令查看man 3 setenv

      可见,两个函数都是成功返回0,失败返回-1,并记录errno信息。

      • 测试代码:
    #include <stdio.h>  
    #include <stdlib.h>  
    #include <string.h>  
       
    int main(void)  
    {  
        char* val;  
        const char* name ="ABC";  
          
        //获取ABC环境变量的值  
        val = getenv(name);  
        printf("No.1  %s=%s
    ", name, val);  
       
        //覆盖写入环境变量  
        setenv(name, "I amsure of that I will get it", 1);  
        printf("No.2%s=%s
    ", name, val);  
          
        val = getenv(name);  
        printf("No.3%s=%s
    ", name, val);  
          
        //删除一个环境变量  
        int ret =unsetenv("ABC");  
        printf("ret =%d
    ",ret);  
          
        val = getenv(name);  
        printf("No.3 %s=%s
    ",name, val);  
           
        return 0;  
    }  
    

    测试结果:

    2.I/O重定向

    • Linux 使用三种流:

    0:stdin 标准输入
    1:stdout 标准输出
    2:stderr 标准错误输出

    1.下面代码证明是shell将输入和输出重定向的,并不将重定向标记和文件名传递给程序。

    #include<stdio.h>  
    int main(int ac,char *av[]){  
        int i;  
        printf("number of args:%d
    ",ac);  
        printf("args are:
    ");  
        for(i=0;i<ac;i++)  
            printf("args[%d]=%s
    ",i,av[i]);  
        fprintf(stderr,"This message is sent to stderr.
    ");  
        return 0;  
    }  
    

    结果:

    3.管道

    管道创建成功以后,创建该管道的进程(父进程)同时掌握着管道的读端和写端。为实现父子进程间通信呢,通常可以采用如下步骤:

    1. 父进程调用pipe函数创建管道,得到两个文件描述符fd[0]、fd[1]指向管道的读端和写端。
    2. 父进程调用fork创建子进程,那么子进程也有两个文件描述符指向同一管道。
    3. 父进程关闭管道读端,子进程关闭管道写端。父进程可以向管道中写入数据,子进程将管道中的数据读出。由于管道是利用环形队列实现的,数据从写端流入管道,从读端流出,这样就实现了进程间通信。

    教材学习中的问题和解决过程

    • 问题1:按发出信号的原因如何分类?
    • 问题1解决方案:

    (1) 与进程终止相关的信号。当进程退出,或者子进程终止时,发出这类信号。
    (2) 与进程例外事件相关的信号。如进程越界,或企图写一个只读的内存区域(如程序正文区),或执行一个特权指令及其他各种硬件错误。
    (3) 与在系统调用期间遇到不可恢复条件相关的信号。如执行系统调用exec时,原有资源已经释放,而目前系统资源又已经耗尽。
    (4) 与执行系统调用时遇到非预测错误条件相关的信号。如执行一个并不存在的系统调用。
    (5) 在用户态下的进程发出的信号。如进程调用系统调用kill向其他进程发送信号。
    (6) 与终端交互相关的信号。如用户关闭一个终端,或按下break键等情况。
    (7) 跟踪进程执行的信号。

    代码调试中的问题和解决过程

    • 问题1:如何实现alarm()time秒时间之后向该进程发送一个定时信号,然后该进程捕获该信号并处理?
    • 问题1解决方案:

    由以下代码可实现:

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <signal.h>
     
    void sig_handler(int num)
    {
        printf("receive the signal %d.
    ", num);
    }
     
    int main()
    {
        signal(SIGALRM, sig_handler);
     
        alarm(2);
     
        while(1){
            pause();
            printf("pause is over.
    ");
        }
     
        exit(0);
    }
    

    结果:

    如果想程序每2秒都定时一下,这样实现也很简单,在处理定时信号的函数中再次定时2秒。

    代码如下:

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <signal.h>
     
    void sig_handler(int num)
    {
        printf("receive the signal %d.
    ", num);
        alarm(2);
    }
     
    int main()
    {
        signal(SIGALRM, sig_handler);
        alarm(2);
        while(1){
            pause();
            printf("pause is over.
    ");
        }
        exit(0);
    }
    

    结果:

    代码托管

    上周考试错题总结

    • 错题1:C语言中,字符串被编码为一个以0结尾的字符数组。

    A .正确
    B .错误

    • 分析:正确。这里分析C语言三个结束符有什么不同?( EOF ‘’ ' ')
      EOF(End of file)是C/C++里面的宏定义,具体定义式是#define EOF -1,表示的是文件的结束标志,值等于-1,一般用在文件读取的函数里面,比如fscanf fgetc fgets等,一旦读取到文件最后就返回EOF标志并结束函数调用。

      ''是转义字符,值等于0,主要用在C风格字符串的末尾,表示字符串结束标志。通常用在和字符串相关的函数里面,如strcmp strcpy等会用到它。

      ' '表示换行符,通常用作一些读取函数的读取结束标志,比如scanf,getchar(),gets()等,一旦遇到' '就结束读取并返回。

    • 错题2:下面和代码可移植性相关的C语言属性有()

    A .#define
    B .typedef
    C .sizeof()
    D .union

    • 分析:#define可以定义宏使得变量可移植,typedef可以使得类型可移植,sizeof()使得不同类型长度可移植。

    其他(感悟、思考等,可选)

    对每一个函数进行代码测试能更好地帮助理解和掌握。

    学习进度条

    代码行数(新增/累积) 博客量(新增/累积) 学习时间(新增/累积) 重要成长
    目标 5000行 30篇 400小时
    第一周 65/65 1/1 10/10
    第三周 120/185 2/3 15/15
    第五周 375/560 3/6 14/29
    第六周 287/847 1/7 14/43

    尝试一下记录「计划学习时间」和「实际学习时间」,到期末看看能不能改进自己的计划能力。这个工作学习中很重要,也很有用。
    耗时估计的公式
    :Y=X+X/N ,Y=X-X/N,训练次数多了,X、Y就接近了。

    参考:软件工程软件的估计为什么这么难软件工程估计方法

    • 计划学习时间:14小时

    • 实际学习时间:14小时

    • 改进情况:

    (有空多看看现代软件工程 课件
    软件工程师能力自我评价表
    )

    参考资料

  • 相关阅读:
    互联网测试开发面试题集锦【转】
    python excel读写数据
    基于python实现Oracle数据库连接查询操作
    基于python实现GET和POST请求及token相关调用
    Notepad++配置替换快捷配置
    GET和POST两种基本请求方法的区别
    HTTP请求的常用方法有哪些
    常见HTTP状态码的含义
    在浏览器中输入URL后,执行的全部过程。(一次完整的http请求过程)
    TCP和UDP的优缺点及区别
  • 原文地址:https://www.cnblogs.com/haoliberale/p/7750145.html
Copyright © 2011-2022 走看看