Linux系统编程开篇

        早都说过要在系统层看看写写了,不过以前真的没搞过这方面的东西,实在是不知道怎么搞。和java一提笔就知道要写什么差了很多。所以,似乎前两周都是看了看书,找找感觉,根本不清楚有什么可以写出来的。好吧,其实,我现在也是不知道写什么,还是没有入门啊,魂淡。
        先来点简单的吧,然后由浅入深。这次写的都是些简单的概念,懂行的童鞋请直接忽视,谢谢。
        系统编程,位于低层,它直接和内核以及核心系统链接库(core system library)交互。系统软件包括你的shell、编译器和调试器、核心实用程序(core utility)、文本编辑器以及系统守护进程(system daemon)。这些组件全部都是基于内核和C链接库的系统软件。血多其他的软件(例如高级GUI应用程序)大多位于高层,只会偶尔进入低层。有些程序设计者会全部投入系统软件的编写,有些只花部分的时间在此。当然,不管哪种,这部分都是整个编写软件的中心。
上面提到的概念,其实很多只是听过,并不是很了解,不过后面肯定会一个一个攻破,真正理解它们。
        系统编程,要从系统调用(system call)开始。系统调用(syscalls简写)其实也就是函数调用(function invocation),从用户空间(文本编辑器,游戏程序等)进入内核(系统调用的基础组件),以便向操作系统请求特定的服务或资源。系统调用的范围从常见的read()和write()到少见的get_thread_area()和set_tid_address()都涵盖在内。
        Linux所实现的系统调用要少于其他操作系统的内核。如linux的i386架构的系统调用大约有300个,而windows据说有上千个。不过,系统调用中有绝大部分(超过90%)是所有架构都会实现的。
        C链接库(libc)是Unix应用程序的中心组建。即使你是以其他语言进行编程,C链接库也能排上用场,通过较高层次链接库的包装,C链接库可以提供核心服务(core service)以及简化系统调用调用。在现代的Linux系统上,C链接库提供自GNU libc,简写为glibc。(貌似更显是系统调用的再上一层了)
        在Linux中,标准的C编译器提供自GNU Compiler Collection(gcc).在linux中,所使用的编译器和系统编程有密切的关系,因为编译器会协助实现C标准和以及系统ABI。
        好了,介绍了这么多概念,就不往下继续介绍了,以后想回顾的时候,在写一些吧。文章收尾,得来点硬货,上点代码吧。
        文章第一章,介绍的是文件I/O。先看看linux下的文件吧。一个文件必须先打开,才可以对他进行读写操作。内核为每一个进程维护一个已打开文件的列表,称为文件列表(file table)。此表是通过对一个非负整数被索引,而这个非负整数被称为文件描述符(file descriptor)。看到了吗,其实java上层的东西也都源于这里,fd在java中也是很常用的。每个Linux进程对文件的打开数都有限制,默认情况下,为1024个,可以最大到1048576。这里可以看到,在android编程中,我们会有碰到过文件打开数超出上限的错误,就是因为这个值的问题,在实际中,应该适当调大,以免程序出问题。(这么一会,就碰到了两个以前比较不清楚出处的地方,看来系统编程真的有很大得可学性!)
        来看看函数,open系统调用:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcnt1.h>

int open(const char *name, int flags);
int open(const char *name, int flags, mode_t mode);

这里mode有很多常见的:O_APPEND, O_WRONLY等。
举个例子:
int fd;
fd = open("/home/teach/pearl", O_WRONLY | O_TRUNC);
if(fd == -1)
/* 错误 */ 

        上面程序代码,会打开/home/teach/pearl以便进行读写,如果文件存在,则将它截短成零长度。因为没有指定O_CREATE标志,文件如果不存在,则open调用会失败。
        所以,想O_TRUNC这个参数,就比先对文件清理,然后再写就快很多。

猜你喜欢

转载自nanapoleon.iteye.com/blog/1684000