Chinaunix首页 | 论坛 | 博客
  • 博客访问: 55673
  • 博文数量: 13
  • 博客积分: 850
  • 博客等级: 准尉
  • 技术积分: 220
  • 用 户 组: 普通用户
  • 注册时间: 2007-09-10 16:20
文章存档

2008年(13)

我的朋友
最近访客

分类: C/C++

2008-10-30 21:45:33

Unix体系结构:
    很多书上一开始往往要讲到操作系统结构,这本书当然也不例外,其实这个结构很抽象。什么内核、系统调用、库函数以及shell等等,给人总是很模糊的,我不喜欢这些,对
于开源项目,最好的解释就是代码伺候。
文件和目录:
    Unix一开始就设定好了一种目录结构,其实就是一棵树,有很明显的树根(和windows相比),而且很明确的树的操作。树根叫“/”.而且为了进程的概念,引入当前目录,上
级目录等概念。其实最早的操作系统应该是Unix。当时写这个操作系统美国佬,还特地发明了一种程序语言,就是C语言。
输入输出:
    Unix上面有三个特殊文件。输入设备、输出设备和出错设备。这个文件个人认为都是系统为了扩展性而设计的,三个文件可以是一种设备,也可以是单纯的文件。他们文件描
述符分别是0,1,2.这是操作系统定的,谁能连接上这三个描述符,谁就是这个三个设备。通常我们用shell打开的程序时,shell把这个三个文件描述符都同时链接到当前终端控制
台。
    说起输入输出,又想起缓冲等概念。一般为了程序,也是操作系统的吞吐量和速度,都喜欢搞一个缓冲区,当然这确实也有效。例如我们最开始学C语言接触的printf输出函数
。这个函数是将我们的输出先放到一个缓冲区里,然后当缓冲区满了,或者程序给出特定标识来刷新缓冲区时,才把我们信息输出到输出设备上。printf是行缓冲,也就是一行满
的时候或者遇到了换行符时候,系统才把我们信息输出。
    当然如何知道printf就是缓冲区输出,还得看它的源代码。
程序和进程:
    有时经常听到别人讨论,也有人问我或者想考我的:进程是什么东东?我通常很简单的回答,进程就是程序,运行中的程序。说完第一句的时候,问的人不免有点自喜,以为
一下就把我给考住了,等我过一会儿再说出第二句的时候,问的人就有点失望了,哈哈。其实我理解也很简单,因为程序和进程,两者都有一个“程”字,所以有它共同点,不同
的是“进”和“序”,很明显,进表示前进、进行,是活的有生命的。序表示序列,有序的东东,是死的。提到进程,给人的第一概念就是fork()函数。其实这个fork和微软的
CreateProcess有很大的不同,他仅仅是CreateProcess前部分,后部分是execve()等系列四个函数。
    对于刚入门的Unix的系列的程序员,大概对这个fork很难理解. if (pid = fork()) 中的pid是什么,为什么同一个函数会返回两次呢?这也不怪,对于写惯了程序的人,肯定
有点难以接受,我们平常接触的程序都只有一个出口,就是return,难道他return 完后,再return一次,这样就出现了矛盾了。拔开乌去见丽日,返回两次是在不同的进程内,在
同一个进程内也只能返回一次,也就是return.因为进程是互相隔离的,所以对于两个进程都不知道对方正在做什么,除非他问对方。这里又出现另一个问题,为什么两个进程在同
一个函数内呢?按我们理解是,代码段一般不能共享的,其实代码段可以共享,也就是两个进程都同时拥有这段代码,所以同一函数可以出现两个进程。
    这里还要提一点的就是,在返回值上Unix和Windows风格不一样,Unix习惯0表示正确,而Windows习惯大于0表示正确,相反则错误。前面我已经提到Unix操作系统最开始设计
的时候就有一人叫出错设备的文件,所以一旦出错,首先代码段出返回一个error整形变量,其次系统会将出错信息输出到出错设备中。
    另外对于出错恢复,Windows一般在例程开始的时候提供一个异常帧,以保证错误可以恢复。Unix系统对于出错恢复并没有做有效的管理,最多在资源占用时候,会延时再试,
出错管理还得程序员自己做。

用户和组:
    对于这个概念,一直很乱七八糟的。什么超级用户、根用户、当前用户、域用户、组用户、组、附加组等等,概念太多,很多书上自认为说得很清楚,但很少我看得出他们说
得很清楚。其实我认为,这些所有概念无非就是这个操作系统是谁的?当前进程是谁?这个用户是谁家里的?分辨出这些就可以了,非要讲些什么支配权、登录名、口令等等乱七
八糟东东,无奈。

信号:
    信号是进程间通信(IPC)一种技术,可以是内核进程,也可以是用户进程。也就是可以运行在内核模式也可用户模式。信号是系统大力支持一种通信方式,而且特定为信号设
计了一个数据结构,并且在内核中(比如中断)深入支持。你可以添加自己的信号,也可以修改系统信号,当然你得按系统给你设定的方式做些事情。
    我认为信号通信最大的好处就是简单,发送者只需发送一个信号代码即可。没有消息那么多信息,没有socket那么复杂,没有管道那么多同步。
时间值:
    长期以来,Unix一直使用两种不同的时间值:
    1,日历时间。该值是从1970年1月1日00:00:00以来所经过的秒数。它时系统硬件Bios专门记录的。(time_t)
    2,进程时间。它是系统时钟中断产生的系统滴答所记录的数值。(clock_t)
其实二者主要是字宽不同,前者是long long.后者是long.
二,标准化及实现
    由于Unix是开源项目,所以由此产生很多版本,比如最早的AT&T实验室的SVR4,加州大学伯克利分校的FreeBSD,当今流行开源系统Linux,Apple公司的Max OS X,Sun公司的
Solaris。
系统之多,就会引起分歧。各行各的,就会导致程序很乱,必须一套大家共遵循的标准才行。
首先是C语言,因为大多操作系统都是用C语言开发的。
    ISO C:即国际标准化组织制定的C标准规范。1999年ISO C标准被更新为ISO/IEC 9899:1999。
其次就是系统调用规范,几乎每个操作系统都提供一套自己的系统调用,因为它是内核模式运行的,不同于用户模式,是程序开发的根本,所以也必须标准化。
    IEEE POSIX:POSIX是一系列由IEEE制定的标准,也是可移值操作系统的接口。现行成熟标准是POSIX.1,由Austin Group开发工作组维护。
    Single UNIX Specification:他也POSIX标准,只是他是POSIX.1的一个超集,扩展了POSIX.1所提供的功能。相应的接口也被改称为X/Open系统接口,由Open Group开发维护
。2002年被ISO批准为国际标准ISO/IEC 9945:2002。
    每个操作系统为用户提供开发接口,也都定义了一套系统数据类型。以下是/usr/include/sys/types.h文件内容,提供了系统基本数据类型定义。
  
/*
* POSIX Standard: 2.6 Primitive System Data Types
*/
#ifndef _SYS_TYPES_H
#define _SYS_TYPES_H 1
#include
__BEGIN_DECLS
#include
#ifdef __USE_BSD
# ifndef __u_char_defined
typedef __u_char u_char;
typedef __u_short u_short;
typedef __u_int u_int;
typedef __u_long u_long;
typedef __quad_t quad_t;
typedef __u_quad_t u_quad_t;
typedef __fsid_t fsid_t;
#  define __u_char_defined
# endif
#endif
typedef __loff_t loff_t;
#ifndef __ino_t_defined
# ifndef __USE_FILE_OFFSET64
typedef __ino_t ino_t;
# else
typedef __ino64_t ino_t;
# endif
# define __ino_t_defined
#endif
#if defined __USE_LARGEFILE64 && !defined __ino64_t_defined
typedef __ino64_t ino64_t;
# define __ino64_t_defined
#endif
#ifndef __dev_t_defined
typedef __dev_t dev_t;
# define __dev_t_defined
#endif
#ifndef __gid_t_defined
typedef __gid_t gid_t;
# define __gid_t_defined
#endif
#ifndef __mode_t_defined
typedef __mode_t mode_t;
# define __mode_t_defined
#endif
#ifndef __nlink_t_defined
typedef __nlink_t nlink_t;
# define __nlink_t_defined
#endif
#ifndef __uid_t_defined
typedef __uid_t uid_t;
# define __uid_t_defined
#endif
#ifndef __off_t_defined
# ifndef __USE_FILE_OFFSET64
typedef __off_t off_t;
# else
typedef __off64_t off_t;
# endif
# define __off_t_defined
#endif
#if defined __USE_LARGEFILE64 && !defined __off64_t_defined
typedef __off64_t off64_t;
# define __off64_t_defined
#endif
#ifndef __pid_t_defined
typedef __pid_t pid_t;
# define __pid_t_defined
#endif
#if (defined __USE_SVID || defined __USE_XOPEN) && !defined __id_t_defined
typedef __id_t id_t;
# define __id_t_defined
#endif
#ifndef __ssize_t_defined
typedef __ssize_t ssize_t;
# define __ssize_t_defined
#endif
#ifdef __USE_BSD
# ifndef __daddr_t_defined
typedef __daddr_t daddr_t;
typedef __caddr_t caddr_t;
#  define __daddr_t_defined
# endif
#endif
#if (defined __USE_SVID || defined __USE_XOPEN) && !defined __key_t_defined
typedef __key_t key_t;
# define __key_t_defined
#endif
#ifdef __USE_XOPEN
# define __need_clock_t
#endif
#define __need_time_t
#define __need_timer_t
#define __need_clockid_t
#include
#ifdef __USE_XOPEN
# ifndef __useconds_t_defined
typedef __useconds_t useconds_t;
#  define __useconds_t_defined
# endif
# ifndef __suseconds_t_defined
typedef __suseconds_t suseconds_t;
#  define __suseconds_t_defined
# endif
#endif
#define __need_size_t
#include
#ifdef __USE_MISC
/* Old compatibility names for C types.  */
typedef unsigned long int ulong;
typedef unsigned short int ushort;
typedef unsigned int uint;
#endif
/* These size-specific names are used by some of the inet code.  */
#if !__GNUC_PREREQ (2, 7)
/* These types are defined by the ISO C99 header . */
# ifndef __int8_t_defined
#  define __int8_t_defined
typedef char int8_t;
typedef short int int16_t;
typedef int int32_t;
#  if __WORDSIZE == 64
typedef long int int64_t;
#  elif __GLIBC_HAVE_LONG_LONG
__extension__ typedef long long int int64_t;
#  endif
# endif
/* But these were defined by ISO C without the first `_'.  */
typedef unsigned char u_int8_t;
typedef unsigned short int u_int16_t;
typedef unsigned int u_int32_t;
# if __WORDSIZE == 64
typedef unsigned long int u_int64_t;
# elif __GLIBC_HAVE_LONG_LONG
__extension__ typedef unsigned long long int u_int64_t;
# endif
typedef int register_t;
#else
/* For GCC 2.7 and later, we can use specific type-size attributes.  */
# define __intN_t(N, MODE) \
  typedef int int##N##_t __attribute__ ((__mode__ (MODE)))
# define __u_intN_t(N, MODE) \
  typedef unsigned int u_int##N##_t __attribute__ ((__mode__ (MODE)))
# ifndef __int8_t_defined
#  define __int8_t_defined
__intN_t (8, __QI__);
__intN_t (16, __HI__);
__intN_t (32, __SI__);
__intN_t (64, __DI__);
# endif
__u_intN_t (8, __QI__);
__u_intN_t (16, __HI__);
__u_intN_t (32, __SI__);
__u_intN_t (64, __DI__);
typedef int register_t __attribute__ ((__mode__ (__word__)));

/* Some code from BIND tests this macro to see if the types above are
   defined.  */
#endif
#define __BIT_TYPES_DEFINED__ 1

#ifdef __USE_BSD
/* In BSD is expected to define BYTE_ORDER.  */
# include
/* It also defines `fd_set' and the FD_* macros for `select'.  */
# include
/* BSD defines these symbols, so we follow.  */
# include
#endif /* Use BSD.  */

#if defined __USE_UNIX98 && !defined __blksize_t_defined
typedef __blksize_t blksize_t;
# define __blksize_t_defined
#endif
/* Types from the Large File Support interface.  */
#ifndef __USE_FILE_OFFSET64
# ifndef __blkcnt_t_defined
typedef __blkcnt_t blkcnt_t;  /* Type to count number of disk blocks.  */
#  define __blkcnt_t_defined
# endif
# ifndef __fsblkcnt_t_defined
typedef __fsblkcnt_t fsblkcnt_t; /* Type to count file system blocks.  */
#  define __fsblkcnt_t_defined
# endif
# ifndef __fsfilcnt_t_defined
typedef __fsfilcnt_t fsfilcnt_t; /* Type to count file system inodes.  */
#  define __fsfilcnt_t_defined
# endif
#else
# ifndef __blkcnt_t_defined
typedef __blkcnt64_t blkcnt_t;    /* Type to count number of disk blocks.  */
#  define __blkcnt_t_defined
# endif
# ifndef __fsblkcnt_t_defined
typedef __fsblkcnt64_t fsblkcnt_t; /* Type to count file system blocks.  */
#  define __fsblkcnt_t_defined
# endif
# ifndef __fsfilcnt_t_defined
typedef __fsfilcnt64_t fsfilcnt_t; /* Type to count file system inodes.  */
#  define __fsfilcnt_t_defined
# endif
#endif
#ifdef __USE_LARGEFILE64
typedef __blkcnt64_t blkcnt64_t;     /* Type to count number of disk blocks. */
typedef __fsblkcnt64_t fsblkcnt64_t; /* Type to count file system blocks.  */
typedef __fsfilcnt64_t fsfilcnt64_t; /* Type to count file system inodes.  */
#endif

/* Now add the thread types.  */
#if defined __USE_POSIX199506 || defined __USE_UNIX98
# include
#endif
__END_DECLS
#endif /* sys/types.h */
阅读(919) | 评论(0) | 转发(0) |
0

上一篇:文件I/O操作

下一篇:new和delete理解

给主人留下些什么吧!~~