unix 基础知识
DIR 表示目录的结构体,类似于FILE的内部结构,能够存储目录的相关信息;
dirent 表示目录和文件的结构,存储目录或文件的相关信息;
stat 表示文件详细信息的结构,存储文件的大小,创建时间,修改时间等;
三种结构体的具体信息如下:
struct
__dirstream
{
void *__fd;
char *__data;
int __entry_data;
char *__ptr;
int __entry_ptr;
size_t __allocation;
size_t __size;
__libc_lock_define (, __lock)
};
{
void *__fd;
char *__data;
int __entry_data;
char *__ptr;
int __entry_ptr;
size_t __allocation;
size_t __size;
__libc_lock_define (, __lock)
};
typedef
struct
__dirstream DIR;
struct dirent
{
long d_ino; /* inode number 索引节点号 */
unsigned short d_reclen; /* length of this d_name 文件名长 */
unsigned char d_type; /* the type of d_name 文件类型 */
char d_name [NAME_MAX+1]; /* file name (null-terminated) 文件名,最长255字符 */
}
struct stat {
mode_t st_mode; //文件访问权限
ino_t st_ino; //索引节点号
dev_t st_dev; //文件使用的设备号
dev_t st_rdev; //设备文件的设备号
nlink_t st_nlink; //文件的硬连接数
uid_t st_uid; //所有者用户识别号
gid_t st_gid; //组识别号
off_t st_size; //以字节为单位的文件容量
time_t st_atime; //最后一次访问该文件的时间
time_t st_mtime; //最后一次修改该文件的时间
time_t st_ctime; //最后一次改变该文件状态的时间
blksize_t st_blksize; //包含该文件的磁盘块的大小
blkcnt_t st_blocks; //该文件所占的磁盘块
}
用户标识和组标识
struct dirent
{
long d_ino; /* inode number 索引节点号 */
unsigned short d_reclen; /* length of this d_name 文件名长 */
unsigned char d_type; /* the type of d_name 文件类型 */
char d_name [NAME_MAX+1]; /* file name (null-terminated) 文件名,最长255字符 */
}
struct stat {
mode_t st_mode; //文件访问权限
ino_t st_ino; //索引节点号
dev_t st_dev; //文件使用的设备号
dev_t st_rdev; //设备文件的设备号
nlink_t st_nlink; //文件的硬连接数
uid_t st_uid; //所有者用户识别号
gid_t st_gid; //组识别号
off_t st_size; //以字节为单位的文件容量
time_t st_atime; //最后一次访问该文件的时间
time_t st_mtime; //最后一次修改该文件的时间
time_t st_ctime; //最后一次改变该文件状态的时间
blksize_t st_blksize; //包含该文件的磁盘块的大小
blkcnt_t st_blocks; //该文件所占的磁盘块
}
用户标识和组标识
在文件使用权限方面,使用用户和组标识有利于时间和空间效率,因为存放文件的用户标识和组标识只需要4个字节,如果存放用户名将花费更长的磁盘空间,在判断用户权限时,比较用户id也比比较字符串简单高效; 口令文件中,存放了用户标识和组标识与名称的映射关系。
信号
信号是通知进程发生了某种事件的一种技术。
时间值
日历时间 : time_t ; 世界标准时间
进程时间(cpu时间):度量进程使用的中央处理机资源 ,以时钟滴答计算 ,历史上曾取每秒50、60或100个时钟滴答 ; clock_t 用来保存这种时间
线程
线程同步:线程按照次序依次协同运行。
在现代计算机系统中,存储器访问需要多个总线周期,多处理器的总线周期通常在多个处理器上是交叉的,所以无法保证数据时顺序一致的。如果是多进程或多线程需要进行线程间的同步。
可以通过使用互斥量来实现线程的同步,从而保证数据的一致性。
在使用互斥变量以前,必须首先对它进行初始化,对于静态分配的互斥量用静态的方式进行初始化,对于动态分配的互斥量(通过malloc)需要动态初始化,并且在释放内存前需要调用destroy。
文件I/O
关键字:
文件描述符
文件
I/O原子操作
当多进程同时操作同一个文件时,涉及到进程对文件的互斥操作,主要是写文件这方面。 要进程操作的保证原子性 方法一 是打开文件时加上(O_APPEND)参数, 使得每次写之前都将文件定位到文件末尾。 其他方法还有 互斥访问常用方法 互斥锁等;还有就是 Single UNXI specification XSL扩展,该扩展允许原子性地定位于I/O, 函数pread() pwrite()
ioctl 函数
unix 中这个函数可以做有关I/O的很多事情,不用 open() 、read()、write()、close()、lseek()、dup()等表示的操作I/O,基本都能用它表示,如 回去设备文件的初始信息、设置设备文件的缓存大小、内存映射、打开设备等操纵。
系统为不同种类的设备提供通用的ioctl(), 设备驱动程序可以定义自己专用的一组ioctl命令 ,设备类别包括有 文件、磁带、套接字、终端等。 ioctl() 函数相当于一个I/O 杂货铺,很多事情多可以做。
标准I/O
关键字
流与FILE对象
流, 标准I/O打开文件 文件与流关联,单字节和多字节字符集,流最初被创建时没有定向,即没指定单字节还是多字节,fwide(),
标准I/O提供三种类型的缓冲
- 全缓冲:填满标准的I/O缓冲区后才进行实际的I/O操作。对于驻留在磁盘上的文件通常是由标准I/O库实施全缓冲。 术语 "冲洗" 说明I/O缓冲区的写操作,可以是系统自动冲洗,也可以调用fflush();
- 行缓冲:当在输入输出中遇到换行符时,标准I/O库执行实际的I/O操作,允许我们一次输入输出一个字符,但一行以后才执行操作, 当流涉及到一个终端时,通常使用行缓冲。
- 不缓冲:是指标准I/O库对字符不进行缓冲存储。
ISO C 要求缓冲特征
标准输出和标准输入不涉及交互式设备时,才是全缓冲;
标准出错不可能是全缓冲,要求快速输出;
设置缓冲函数: setbuf(),setvbuf()
打开流
fopen() , freopen() , fdopen()
读写标准I/O
有三种不同类型的非格式化I/O 操作
1. 每次一个字符,getc()【宏】、fgetc()、getchar(), 判断是到了文件尾还是出错 ferrro()、feof(); 清楚出错标志和结束标志 clearerr(); 送压回流中,ungetc(); 输出函数:putc(),fputc()、putchar() ;
2.每次一行 I/O ,fgets(),该函数可以设置缓冲区长度,并且换行符也写入缓冲区,对于超过缓冲区部分返回一个不完整行,缓冲区以null结束,下次继续读取该行;gets() 不可以指定缓冲区长度,不将换行符写入缓冲区;
3.直接I/O ,每次I/O输入输出某种数量的对象; fread() 、fwrite()
定位流
ftell()、feek()、ftello()
格式化输出
printf()、 fprint()、sprint()、snprintf()
标准I/O
ISO C 标准说明,处理很多细节,如缓冲区的分配等
标准I/O 库的一个不足之处是效率不高,这与它需要复制的数据量有关; 内核和标准I/O缓冲之间, 标准I/O缓冲与用户程序之间; 可以通过返回指向数据行的指针,而不是复制数据行来提高效率; 其他方法还有 内存映射等;
标准I/O提供三种类型的缓冲
- 全缓冲:填满标准的I/O缓冲区后才进行实际的I/O操作。对于驻留在磁盘上的文件通常是由标准I/O库实施全缓冲。 术语 "冲洗" 说明I/O缓冲区的写操作,可以是系统自动冲洗,也可以调用fflush();
- 行缓冲:当在输入输出中遇到换行符时,标准I/O库执行实际的I/O操作,允许我们一次输入输出一个字符,但一行以后才执行操作, 当流涉及到一个终端时,通常使用行缓冲。
- 不缓冲:是指标准I/O库对字符不进行缓冲存储。
ISO C 要求缓冲特征
标准输出和标准输入不涉及交互式设备时
- struct stat {
- mode_t st_mode; //文件访问权限
- ino_t st_ino; //索引节点号
- dev_t st_dev; //文件使用的设备号
- dev_t st_rdev; //设备文件的设备号
- nlink_t st_nlink; //文件的硬连接数
- uid_t st_uid; //所有者用户识别号
- gid_t st_gid; //组识别号
- off_t st_size; //以字节为单位的文件容量
- time_t st_atime; //最后一次访问该文件的时间
- time_t st_mtime; //最后一次修改该文件的时间
- time_t st_ctime; //最后一次改变该文件状态的时间
- blksize_t st_blksize; //包含该文件的磁盘块的大小
- blkcnt_t st_blocks; //该文件所占的磁盘块
- };