第七章 数据管理
内存管理
分配内存
#include<stdlib.h> #include<stdio.h> char *memptr = (char *) malloc(1024);//分配1K的内存
释放内存
#include<stdlib.h> #include<stdio.h> char *memptr = (char *) malloc(1024);//分配1K的内存 free(memptr);//释放内存
Linux支持虚拟内存,内核会将暂时不用的内存块的内容写到硬盘上,用作虚拟内存的硬盘部分被称为交换空间(Swap Space)。
Linux将所有的内存以页为单位进行划分。每当程序试图访问内存时,就会发生虚拟内存到物理内存的转换。
如果一个内存页面未被使用,则将其从物理内存转移到交换空间(换页)。
如果程序试图访问已经置换到交换空间的内存页的数据,则将内存页从交换空间再次置换到物理内存。
文件锁定
多任务,多用户下,程序经常共享文件数据,建立某种控制文件的方式非常重要。
两种应用:(1)以原子操作的方式创建锁文件,保证创建的文件是唯一的,不会被其他程序在同一时间创建。(2)允许程序锁定文件的一部分,从而独享对这部分内容的访问。
创建锁文件
简单来说就是创建一个唯一的文件,并保证同一时间其他程序不会创建相同的文件。
锁文件只是建议锁,不是强制锁。即锁文件只是指示器的作用,需要程序互相协作使用它们。
//lock1.c #include<unistd.h> #include<stdlib.h> #include<stdio.h> #include<fcntl.h> #include<errno.h> int main(){ int file_desc; int save_errno; file_desc = open("/tmp/LCK.test",O_RDWR | O_CREAT | O_EXCL,0444); if(file_desc == -1){ save_errno = errno; printf("Open failed with error:%d\n",save_errno); } else{ printf("Open success\n"); } exit(0); }
执行
wuchao@:~/linux_program/CH07$ ./lock1 Open success wuchao@:~/linux_program/CH07$ ./lock1 Open failed with error:17
第一次执行时,文件不存在,所有调用open成功,第二次文件存在,所有调用失败。open返回-1。
区域锁定
#include<fcntl.h> int fcntl(int fildes, int command, struct flock *flock_structure );
command参数有以下选项:
F_GETLK
获取文件的锁信息
F_SETLK
加锁或解锁
F_SETLKW
同F_SETCL,在无法获取锁时,一直等待,直到获取到锁或收到一个信号。
flock结构体如下:
short l_type
取值如下:
F_RDLCK:共享(或读)锁。多个进程可以拥有同一文件的同一区域的共享锁。只要任意一个进程拥有一把共享锁,就没有进程可以获得该区域的独占锁。为了获取共享锁,文件必须以读或读写打开。
F_UNCLK:解锁
F_WRCLK:独占(或写)锁。只有一个进程可以在文件的特定区域拥有一把独占锁。只要任意一个进程有了这把锁,其他进程无法在该区域获得任何类型的锁。为了获取独占锁,文件必须以写或读写打开。
short l_whence
定义了l_start的相对偏移值,l_whence常设为SEEK_SET,此时l_start从文件的开始计算。
取值如下:
SEEK_SET:文件头
SEEK_CUR:当前位置
SEEK_END:文件尾
short l_start
该区域的第一个字节。
short l_len
该区域的字节数。
short l_pid
持有锁的进程标识符。
锁状态下的读写操作
当对文件区域加锁后,必须使用底层read和write访问文件数据。因为fread和fwrite会对读写的数据进行缓存。
死锁
程序A,B需要同时更新同一个文件中的字节1和字节2,程序A选择先更新字节2,程序B选择先更新字节1。
两个程序同时启动,程序A先锁定字节2,程序B先锁定字节1。程序A尝试锁定字节1,但字节1被B锁定,A在那里等待。接着B尝试锁定2,但被A锁定,B也在等待。
此时,两个程序都无法继续下去。