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

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

    教材学习内容总结

    浏览了正章,重点学习了以下几个点

    前些时候写过基于fork(),execvp()和wait()实现类linux下的bash——mybash,里面有着我关于fork(),execvp()和wait()的一点见解。

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

    • 问题1:怎么做到fork函数返回两次,并且两次不同(一次为子进程的pid,一次为0)?

    • 问题1的解决:每一个进程都有属于自己的pcb来存储关于本进程的相关数据,而PCB在是以结构体形态存在于内存中的,在调用fork函数的时候,系统会复制一份PCB给子进程(copy_thread),里面保存了相关寄存器的内容——pt_regs,这时修改pt_regs里面的ax寄存器内容使之为0,这样当返回至用户态时就保证了返回值为0;

    • 问题2:怎么对于僵死子进程,此时父进程已终止,子进程由谁回收,且父进程的父进程是谁,是其子进程的“爷爷”进程吗,回收父进程的是谁,是“爷爷”进程还是init进程?

    • 问题2解决:没有找到相关的介绍,所以就简单做了个实验来解释,首先假设回收该进程的都是其父进程,被回收的都是子进程,这样就可以通过使用getppid()函数来得到回收进程的pid号,下面是几个测试代码:

    • 测试1:测试父进程等待子进程并回收其

    #include<sys/types.h>
    #include<sys/wait.h>
    #include<unistd.h>
    #include<stdio.h>
    #include<stdlib.h>
    void main()
    {
    	int i=0;
    	pid_t pid;
    	printf("p_pid=%d
    ",getppid());
    	pid=fork();
    	wait(NULL);
    	if(pid==0){
    	//sleep(10);
    	printf("cp_pid=%d
    ",getppid());
    	}
    	printf("this pid is %d
    ",getpid());
    	exit(1);
    }
    

    • 运行截图:
    • 测试2:测试父进程已终止,子进程此时的父进程pid号是多少,即回收该子进程的进程是多少
    #include<sys/types.h>
    #include<sys/wait.h>
    #include<unistd.h>
    #include<stdio.h>
    #include<stdlib.h>
    void main()
    {
    	int i=0;
    	pid_t pid;
    	printf("p_pid=%d
    ",getppid());
    	pid=fork();
    	//wait(NULL);
    	if(pid==0){
    	sleep(10);
    	printf("cp_pid=%d
    ",getppid());
    	}
    	printf("this pid is %d
    ",getpid());
    	exit(1);
    }
    
    • 运行截图:

    • 通过以上实验,可以看出,父进程调用fork函数生成的子进程的ID号刚好比其多一(父进程ID:50367,子进程ID:50368),再者,当父进程等待并回收子进程时,子进程显示的父进程ID号刚好等于50367,这就符合了以上假设,但有个问题,此时的父进程的父进程ID号是50171,并非书上所写的init祖先进程的ID号(init ID号为1),这是一个问题;以上是根据测试1得到的结论;

    • 测试2得到的结论是,当产生自己的父进程终止后,回收自己的总是ID号为1503的进程,也不符合书上回收僵尸进程的为init进程

    • 现在就有两种可能,第一种,书上说错了,但问题出现了,为什么回收子进程的是ID号为1503的进程,而回收父进程的是ID号为50171的进程,如果说ID号为1503的进程是作为回收进程的专有进程,那为什么会有差异,但这样也有解释就是回收僵尸进程和正常回收进程是不一样的进程做的事;第二种可能就是假设错了,不能简单的通过getppid()这个函数就判断回收该进程的是谁,如果是这样,那么就简单的按照书上所给前提下个结论:正常回收子进程的都是其父进程,而回收父进程的都是init(祖先)进程,对于僵尸进程都由init代为回收,同时得到另一个结论,不能简单实用getppid()函数得到回收进程的进程的ID号;

    • 翻看到第八章后面发现了几个bash指令,其中之一就是ps指令(用于打印出当前系统中的进程(包括僵尸进程));通过ps aux|grep 1503ps aux|grep 50171得到如下图,其中每行的最后一个字段代表command,即执行者是谁,这样就顺藤摸瓜得到了./Fork的父进程是ID号为50171的由bash执行的进程,所以理所应当在父进程终止后有由bash回收,而对于ID号为1503的进程的执行者是/sbin/upstart,这里的/sbin/upstart就是在书中提到的专门回收进程的“init”进程,但并不是所有进程的祖先,这里还是回到ps指令得到的信息来看,这里是存在者名为init的祖先进程的,即ID号为1的进程,但此时的这个祖先进程不在执行所有的僵死进程的回收了,而将此功能赋予给了/sbin/upstart创造出来的ID号为1503的进程,由她来收集僵死进程。


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

    • 问题1:statistics运行时,总会出现xargs cat:因信号13而终止的错误,我尝试把.c改成.java,就没有那样的错误了,我百度但没有关于信号13的解释,我决定重读statistics脚本;

    • 问题1的解决:

    语句 含义
    find . -name "*.c" 找到当前目录下所有.c文件
    xargs cat 这里的xargs相当于一个连接管道,将find找到的文件输送到cat指令下,并执行
    grep -v $ grep -v指的是捕捉非-v后面的其他内容,$指的是空行
    wc -l 统计文档里的行数
    • 解释了之后就清晰多了,但依然没有找到错误何在,如果不是脚本里面的错,那就是捕捉到的文件的问题,我重新用find . -name "*.c"检索了一遍所有.c文件,发现有个命名是这样的mybash (复件).c文件名存在一个空格,删除该文件后以及其他文件名有空格的文件后,重新运行statistics脚本,结果就正常了。


    代码托管

    结对及互评

    结对队友20155303

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

    这周有点感慨,就是linux其实提供了很多指令供我们学习linux,与其只是去简单的在C语言上做表面功夫,不如深入学习一下linux里的bash指令,往往会有事半功倍的效果。

    学习进度条

    代码行数(新增/累积) 博客量(新增/累积) 学习时间(新增/累积) 重要成长
    目标 5000行 15篇 400小时
    第一周 177/177 1/1 10/10
    第三周 308/485 2/2 12/22
    第五周 277/762 2/4 10/32
    第六周 567/1329 1/5 15/47

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

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

    • 计划学习时间:XX小时

    • 实际学习时间:XX小时

    • 改进情况:

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

    参考资料

  • 相关阅读:
    CSS学习笔记07 盒子模型
    [Android]AndFix使用说明
    [Android]自定义控件LoadMoreRecyclerView
    [算法]Plus One
    [Android]android Service后台防杀
    [Android]android studio预览视图时报错
    [算法]删除无序单链表中值重复出现的节点
    [算法] 将单链表的每K个节点之间逆序
    [Android]热修复框架AndFix测试说明
    [算法]单链表的选择排序
  • 原文地址:https://www.cnblogs.com/elevator/p/7748123.html
Copyright © 2011-2022 走看看