标签:发送 格式 抽象 return rest 成功 signal mkfifo argv
异常控制流(ECF)发生在计算机系统的各个层次,是计算机系统中提供并发的基本机制。在硬件层,异常是由处理器中的事件触发的控制流中的突变。控制流传递给一个软件处理程序,该处理程序进行一些处理,然后返回控制给被中断的控制流。
有四种不同类型的异常:中断、故障、终止和陷阱。当一个外部旧设备,例如定时器芯片或者一个磁盘控制器,设置了处理器芯片上的中断引脚时(对于任意指令)中断会异步地发生控制返回到故障指令后面的那条指令。
一条指令的执行可能导致故障和终止同时发生故障,处理程序会重新启动故障指令,而终止处理程序从不将控制返回给被中断的流。最后,陷阱就像是用来实现向应用提供到操作系统代码的受控的入口点的系统调用的函数调用。
在操作系统层,内核用ECF提供进程的基本概念。进程提供给应用两个重要的抽象:(1)逻辑控制流,它提供给每个程序一个假象,好像它是在独占地使用处理器(2)私有地址空间,它提供给每个程序一个假象,好像它是在独占地使用主存。
在操作系统和应用程序之间的接口处,应用程序可以创建子进程,等待它们的子进程停止或者终止,运行新的程序,以及捕获来自其他进程的信号。
最后,在应用层,C程序可以使用非本地跳转来规避正常的调用/返回栈规则,并且直接从一个函数分支到另一个函数。
execvp()
会从PATH 环境变量所指的目录中查找符合参数file 的文件名,找到后便执行该文件,然后将第二个参数argv传给该欲执行的文件exevp函数调用成功没有返回,所以没有打印出“* * * ls is done. bye”这句话
将ls -l
变换成man -k,代码修改如下
man -k
语句,还是没有返回“* * * man is done. bye”
exec2与exec1的区别就在于exevp函数的第一个参数,exec1传的是ls,exec2直接用的arglist[0],不过由定义可得这两个等价,所以运行结果是相同的
若将exevp函数传入的arglist[0]改为arglist[1],此时exevp函数没有调用成功,于是打印出“* * * ls is done. bye”这句话。
函数中execlp()会从PATH 环境变量所指的目录中查找符合参数file的文件名,找到后便执行该文件,然后将第二个以后的参数当做该文件的argv[0]、argv[1]……最后一个参数必须用空指针(NULL)作结束
以下四个函数中任意一个的运行结果都与其他三个完全一致。
getenv函数是获得环境变量值的函数,参数是环境变量名name,例如”HOME”或者”PATH”。如果环境变量存在,那么getenv函数会返回环境变量值,即value的首地址;如果环境变量不存在,那么getenv函数返回NULL。
environvar.c代码简单打印环境变量表,运行结果如下
其中s为命令行字符串,delimiters为分割符,argvp为指向参数数组的指针,如果转化成功则返回标记的个数,如果错误则返回-1,并设置errno
由于argtest.c中有如下代码: if (argc != 2) { fprintf(stderr, "Usage: %s string\n", argv[0]); return 1; }
只有当输入命令的个数等于2时,才能显示命令正确的结果。
看了这几个c文件后,我有一些思考:
1.为什么是 int makeargv(const char s, const char delimiters, char * argvp)?
把最后一个参数理解为向字符串数组取地址(从左到右,第一个代表取地址,后两个 代表上文中说过的字符串数组)
2.关于strtok函数?
strtok函数用来将字符串分割成一个个片段,它的原型是char strtok(charr s[],const char delim)。只要在s中遇到delim中包含的字符(不一定是delim),就把这个字符改成\0。每次调用成功后返回的都是被分割出的片段的指针。
consumer.c代码运行:
producer.c代码运行:
testmf.c代码中调用了mkfifo函数 mkfifo(FIFONAME, 0777);//依据FIFONAME创建fifo文件,0777依次是相应权限
mkfifo()建立的FIFO文件其他进程都可以用读写一般文件的方式存取
关于testbuf
\n
是一样的?testbuf3.c将内容格式化输出到标准错误、输出流中
?testpid.c代码输出当前进程pid和当前进程的父进程的pid
testsystem.c代码中system()——执行shell命令,也就是向dos发送一条指令。这里是后面可以跟两个参数,然后向dos发送这两个命令,分别执行
如下图,输入ls和dir两个指令后,可以看到分别执行了
pipe用来创建管道并将其两端连接到两个文件描述符,array[0]为读数据端的文件描述符,而array[1]则为写数据端的文件描述符,内部则隐藏在内核中,进程只能看到两个文件描述符
listargs.c 代码运行结果如下,证明了shell并不将重定向标记和文件名传递给程序
sigdemo2.c中: SIGDFL,SIGIGN 分别表示无返回值的函数指针,指针值分别是0和1,这两个指针值逻辑上讲是实际程序中不可能出现的函数地址值。 SIGDFL:默认信号处理程序 SIGIGN:忽略信号的处理程序
sigdemo3.c根据代码,在read函数不发生错误的情况下输入什么,就输出什么,输入的Ctrl+C也无法终止程序,只有输入quit的时候才会退出
sigactdemo.c中sigaction()会依参数signum指定的信号编号来设置该信号的处理函数。参数signum可以指定SIGKILL和SIGSTOP以外的所有信号
int sigaction(int signum,const struct sigaction *act ,struct sigaction *oldact);
sigactdemo.c执行如下
SA_RESETHAND:当调用信号处理函数时,将信号的处理函数重置为缺省值SIG_DFL
SA_RESTART:如果信号中断了进程的某个系统调用,则系统自动启动该系统调用
SA_NODEFER :一般情况下, 当信号处理函数运行时,内核将阻塞该给定信号。但是如果设置SA_NODEFER标记,
那么在该信号处理函数运行时,内核将不会阻塞该信号
在运行argtest的时候,出现了问题。
后来发现,应该将argtest.c和makeargv.c,还有freemakeargv.c和argv.h放在同一目录下;运行成功~
argv文件夹中的主要程序是argtest.c
有两种运行方法:
第一种是用-c将所有.c的文件编译成后缀为.o的文件,然后一起编译成可执行文件。
第二种方法是直接将所有的.c文件编译成可执行文件,运行结果是一样的。
这周学习的是第八章的内容,娄老师提前在课上就讲了一些,并且强调了其重要性。因为老师的强调,我更加认真去看了这部分的内容,并通过代码来实践。这学期还有一门操作系统的必修课,我学到了很多与进程有关的知识。因此我觉得学科之间是有共同点的,所以我想通过这一章的学习来巩固这部分知识并且做到学科间的融合。但是这一章还是有好几个函数的运行和原理不是很明白,需要多多琢磨。学过的知识还要温习,没学过的新知识要触类旁通,这样才会更有效率!
代码行数(新增/累积) | 博客量(新增/累积) | 学习时间(新增/累积) | 重要成长 | |
目标 | 5000行 | 30篇 | 400小时 | |
第一周 | 0/0 | 1/2 | 20/20 | |
第二周 | 58/58 | 1/3 | 20/40 | |
第三周 | 150/208 | 1/4 | 22/62 | |
第五周 |
150/358 | 1/5 | 21/83 | |
第六周 | 136/494 | 1/6 | 25/108 | |
第七周 | 115/609 | 2/8 | 24/132 | |
第八周 | 0/609 | 2/10 | 22/154 | |
第九周 | 109/718 | 3/13 | 20/174 | |
第十周 | 472/1190 | 1/14 | 21/195 | |
第十一周 | 1883/3073 | 3/17 | 21/216 |
20145326蔡馨熠《信息安全系统设计基础》第11周学习总结
标签:发送 格式 抽象 return rest 成功 signal mkfifo argv
原文地址:http://www.cnblogs.com/cxy1616/p/6106886.html