UNIX System Overview
2016-02-04 11:47
337 查看
Unix Architecture
Logging in
登录unix系统时,我们输入的账户密码需要在密码文件中检查。密码文件中包含了用户名,加密的密码,home目录,shell program(/bin/ksh)等等内容。有些系统将密码存放到了其他的文件之中。
shells
shell是一种command-line interpreter用于读取用户输入并且执行指令。用户输入命令可以通过terminal也可以通过shell脚本 来输入。Files and Directories
file system
filename
pathname
Working Directory
每个程序都有一个工作目录。比如doc/memo/joe,就是在工作目录下的doc中的memo目录中的joe目录或者文件。而/usr/lib就是绝对路径,根目录下的usr目录下的Lib目录。Home Directory
Input and Output
File Descriptors
文件描述符是内核用来标志被特殊进程访问的文件,通常是小的非负整数。文件描述符可以用来完成read和write操作。Standard input, Standard Output, and Standard Error
无论哪个程序运行的时候,所有的shell会打开三个描述符-对应于标准input/out/error>当只是简单地运行一个命令的时候,如:
ls
then all three are connected to the terminal.
大部分shell提供重定向的方法,例如:
ls > file.list
就将standard ouput重定向到文件file.list中去。
Unbuffered I/O
无缓冲IO通过函数open,read,write,lseek,and close提供。这些函数都操作file descriptor.Example
使用一个例子演示复制文件1到第二个文件中,使用了重定向。因为我是用的是ubuntu,与书中的代码进行了一些修改,本人亲自实验过,因此代码都是可用的。#include <stdio.h> #include <unistd.h> #define BUFFSIZE 4096 int main(void) { int n; char buf[BUFFSIZE]; while((n = read(STDIN_FILENO, buf, BUFFSIZE))>0) { if(write(STDOUT_FILENO, buf, n) != n) { fprintf(stderr, "write error"); } } if(n < 0) { fprintf(stderr, "read error"); } return 0; }
gcc编译成功后执行:
./a.out < infile > outfile
文件infile重定向为a.out的标准输入,outfile重定向为a.out的标准输出。执行该命令后,infile文件内容会复制到outfile中。
Standard I/O
标准IO在unbuffered I/O之上提供了具有缓冲能力的接口。使用标准IO不需要我们考虑选择合适的缓冲区大小,例如上例的BUFFSIZE。此外标准IO简化了对于输入一行一行的处理。例如:fgets就直接读取完整的一行。最典型的标准IO函数就是
printf。
头文件为
<stdio.h>
接下来对于上一个例子进行改写。
Example
#include <stdio.h> int main(void) { int c; while((c = getc(stdin)) != EOF) { if(putc(c, stdout) == EOF) { fprintf(stderr, "out error!"); } } if(ferror(stdin)) { fprintf(stderr, "input error!"); } return 0; }
此外解释一下代码中的函数功能:
ferror(stdin)用于检查流上的错误,如果标准输入流有错,则报错
Programs and Processes
Program
程序是在硬盘上的可执行文件。一个程序被读进内存中并且被内核执行,内核使用six exec functions中的一种来执行程序。具体的内容会在后续章节讲解。Process and Process ID
进程是程序被执行的过程。一些操作系统使用术语task来指代被执行的程序。
Unix系统使用非负整数的进程ID来区别进程。
Process Control
有三种主要函数进行进程控制:fork exec(has six variants) waitpid
Threads and Thread IDs
通常进程仅仅有一个线程-同一时间一组机器指令执行。在一个进程中所有的线程分享同样的地址空间、文件描述符、stacks、和进程相关的属性。因为共享的特性,所以需要注意线程同步问题。
Error Handling
在UNIX系统函数中产生错误的时候,会返回负数,此外errno会被设置为某值—用于提供额外的信息。
此外一些函数发生错误会返回
null指针。
在头文件
<errno.h>定义了
errno
如果你想在Linux中查询错误常量列表,你需要在
errno(3) manual page中查看。
对于errno有两点需要注意:
1. 如果function没有出错,则不会清除errno的值。因此只有在发生错误后查看errno的值才是有意义的。
2. errno永远不会被设置为0
C标准中有2个函数用来帮助打印错误信息:
#include <string.h> char * strerror(int errnum);
#include <stdio.h> void perror(const char *msg);
Error Recovery
定义在头文件<errno.h>的错误可以被分为两类:致命的和非致命的。只有非致命的(nonfatal)可以被修复。资源相关的非致命错误中,
EBUSY表示共享的资源正在被使用。
EINTR表示interrupts a slow system call.
对于资源非致命错误典型的处理办法就是等待一会儿再试一次。
1.8 User Identification
User ID
用于标示用户,ID 0就是root的用户ID。
Group ID
用户成组,便于共享资源等。1.9 Signals
信号是一种通知进程一些环境已经发生了改变的技术。例如,进程除以0,名为SIGFPE的信号就会发送给进程。
每个进程有三个选择来处理信号:
1. 忽略信号
2. 执行默认的操作
3. 提供自定义的函数来执行。
很多环境都有信号产生,例如终端使用Ctrl+C来打断进程的执行。
另外一个产生信号的方法是调用
killfunction。我们可以调用这个函数来发送信号给另一个进程。
但是:我们必须是另一个进程的拥有者才可以这样做
1.10 Time Values
UNXI系统拥有两种时间值:1. 日历时间
2. 进程时间
对于每个进程拥有三种时间值:
1. clock time(wall clock time)进程运行的总时间,该值也取决于系统运行的其他进程。
2. User CPU time,用户指令的CPU时间。
3. System CPU time,内核中运行该进程的时间。
为了测量这些时间,只需要简单的执行
time(1)命令。例如:
cd /user/include time -p grep _POSIX_SOURCE */*.h > /dev/null
相关文章推荐
- iOS网络编程
- How Many Tables(POJ 1213 求连通分量)
- 01参考资料
- maven创建web项目
- java Map集合框架之LinkedHashMap
- zookeeper的实用场景—
- android studio目录说明
- 自定义ListView实现下拉刷新
- USACO 1.1 ride
- WonderTeam
- 《时间序列分析及应用:R语言》读书笔记--第一章 引论
- (三)activiti框架搭建
- JAVA反射汇总和示例
- sqoop import ERROR sqoop.Sqoop: Got exception running Sqoop: java.lang.RuntimeExceptrion
- 记不住就存下来---- HTML 5 新增通用属性
- Struts2 文件下载(Stream)
- Feeling kind of the sorrow
- unix网络编程str_cli使用epoll实现
- 二叉树的几个基础遍历算法代码
- Objective-C 【OC语法:不能修改 某个对象的 结构体属性的 成员】