设为首页 加入收藏

TOP

UNIX环境高级编程 心得笔记(一)
2017-10-10 21:06:09 】 浏览:7577
Tags:UNIX 环境 高级 编程 心得 笔记

所有操作系统都为运行在它之上的程序提供各种服务,典型的服务包括:执行新程序、打开文件、读写文件、分配存储空间、提供时间等。


UNIX环境高级编程中文第二版PDF高清版 下载地址  http://www.linuxidc.net/thread-2063-1-1.html


严格来说,操作系统是一种软件,它控制计算机硬件资源,提供程序运行环境。这种软件有个专业术语名称:内核。因为它小且位于计算机体系的核心。如下图所示:



上图中的系统调用包裹在内核的外围,隔离开内核以保护内核。同时,系统调用作为和内核沟通的中间桥梁。


公用函数库通常指的是C/C++的标准库,例如libc、glibc、libstdc++、libc++等标准库,不同的标准库是由于不同的系统平台或编译器厂商造成的差异,但追根究底都是使用了底层系统内核的API接口系统调用。这些公用函数库极大的方便了上层开发者的使用,也是整个计算机软件体系(无论任何编程语言)的基础。


shell也是一个软件,该软件负责人机交互,用户和shell进行“对话”,然后shell理解用户的意图来使计算机按用户的想法工作。比如我们使用ls命令告诉shell我们想查看文件夹,shell接收后使用各种底层功能(包括读写文件系统、IO输入输出等)来完成该工作,当然最终的结果是打印文件夹在我们的屏幕上显示给我们看。


公用函数库只是提供了好用的功能,这些功能最终是要我们自己来使用的,当我们作为软件开发者的时候,可以调用公用函数库来使用某些功能,如果公用函数库提供的功能不好用或者没有提供,我们也可以直接使用系统调用来请求服务。


上图的内核是严格意义上的操作系统软件,广义上来说,操作系统不仅是内核,因为仅有一个内核只能管理硬件,操作系统还要包含一些软件来加以辅助使用计算机,包括shell、公用函数库、系统程序和实用软件。这也是为什么Linux被称作GNU/Linux操作系统的原因,为了简便称其为Linux,实际上Linux之所以能有今天的成绩,并非Linus torvalds的功劳,甚至可以说他被外界过度夸大,因为Linux是从Minix改写而来(1991年,此时内核难度和硬件移植与今天相比不可同日而语),Linux使用了大量的GNU工具组合成了Linux系统,其后Linux的发展壮大也是广大志愿者黑客出力,所以说Linux的成绩并非Linus torvalds的功劳,他被外界过度神话了。


前面说到shell,要提一下C shell的作者,当初C shell被开发出来之后,由于功能多而广泛流传使用,其开发者是Bill Joy。与Linus torvalds相比,Bill Joy才是真正的大神人物,Vi、TCP协议、C shell的开发作者,BSD内核贡献者,Java创始人之一、SUN公司的合伙创办人,曾有人开玩笑说:和Bill Joy见面,一定要三次握手:)


UNIX系统登录涉及到用户名和密码,以及登录后负责交互对话的shell版本,用户名和shell由配置文件/etc/passwd决定,密码由配置文件/etc/shadow决定。



 


UNIX文件系统是一直树形层次结构,有一个根,是最根本的起点,它是“/”。在文件系统中,目录本质上也是一个文件,其内容是目录项的记录。每个目录项都是一个文件名,还包含一些文件属性的说明信息,比如权限、大小、时间等。


创建新目录时文件系统会自动创建两个文件夹:.(点)和 ..(点点), .(点)表示当前目录,比如我需要拷贝/etc目录下的a文件到当前目录,那么就可以这么做:


 上面使用cp命令将/etc/a这个文件拷贝到当前目录下。


 


..(点点)表示父目录,比如我需要将当前目录下的b文件拷贝到上一层父目录中,则可以这么做:


上面使用cp命令将当前目录下的b文件拷贝到上一层路径中,而不需要显式给出上层具体路径。


有一个特殊的情况,那就是根目录“/”下的.(点)和 ..(点点)是同一个路径,都是“/”。


由斜线“/”开头的路径都是绝对路径,反之则是相对路径。


下面是一个用C++实现的ls(1)命令小代码:


关于“ls(1)”中“(1)”指的是命令章节是属于第一章之内的,UNIX命令通常都会有一个说明手册,手册中对命令有详细说明,但随着命令功能和说明的增加,说明手册页数越来越多,之后便对命令进行了分门别类,通常是1-8总共8中分类,具体是:


1、Standard commands (标准命令)
2、System calls (系统调用)
3、Library functions (库函数)
4、Special devices (设备说明)
5、File formats (文件格式)
6、Games and toys (游戏和娱乐)
7、Miscellaneous (杂项)
8、Administrative Commands (管理员命令)


默认搜索命令时是从最低编号开始搜索,如果搜索到即停止。有时某个命令存在多个编号说明,那么我们就需要指明章节编号。比如 read 命令,该命令既有编号1的命令说明,又有编号2的说明,如果我们想要编号2,则可以具体指明,如下:


或者


每个进程都有一个工作目录,一般称为当前工作目录,进程可以用chdir来更改其工作目录。在登录那里,shell程序的工作目录设置为home目录,该目录通常从/etc/passwd配置文件中获得。


在UNIX系统中输入和输出是经过抽象的,所有的输入和输出底层系统实现都是通过文件抽象来完成的。当我们要读写时,必须要对“文件”进行,这里的文件是UNIX系统哲学中的“一切皆文件”中的“文件”。当我们读写时,是在对抽象的文件进行读写,而实际上该文件可能管理映射到硬件,也可能是一个socket套节字。


对于文件的抽象,是通过文件描述符实现的,打开一个文件得到一个文件描述符,它通常是非负数的,我们对该文件描述符进行读写。


标准输入、标准输出和标准错误也是三个文件描述符,且一般情况下,它们被shell默认打开并默认被系统映射到硬件设备。我们可以使用“ < "和" >”来重定向这三个文件描述符默认打开的设备。


UNIX系统为我们提供了几个用于文件IO的系统调用:open、read、write、lseek、close,它们都使用文件描述符来操作文件,并且不带缓冲。


利用上述系统调用和重定向功能,我们能够简单的写一个小程序来复制普通文件( regular file ),如下:


上述代码中,STDIN_FILENO和STDOUT_FILENO是定义在头文件 unistd.h 中的宏,如下图所示:



该头文件还包含了read和write函数的原形说明,如下图所示:



UNIX系统为我们提供的几个IO系统调用是不带缓冲的,我们也可以使用公用函数库提供的封装过的接口来间接调用系统调用,公用函数库提供的接口是带缓冲的,且无需考虑对缓冲区大小的选择。不过公用函数库提供的接口和系统调用API接口有一些差异,其不再对文件使用文件描述符抽象来进行读写,也不再使用固定字节数来读写,取而代之的是使用文件名和一次读写一个/一行字符(串)。


程序是静态的进程,而进程是运行着的程序。程序本质上是一个存在硬盘上的可执行文件。程序被加载到内存中之后就开始执行,此时程序变成一个动态刻画抽象的进程。每一个进程都有一个标识符,称为进程ID,其

首页 上一页 1 2 3 下一页 尾页 1/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇使用HttpClient调用接口 下一篇关于Java的“找不到或无法加载主..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目