Beginning Linux Programming 笔记(七)数据管理
来源:互联网 发布:sd格式化后数据恢复 编辑:程序博客网 时间:2024/04/30 02:23
数据管理,这对每一个操作系统而言都是必须的。操作系统对数据的管理,可以分成三个方面,内存数据管理,文件管理和抽象数据管理。
内存数据管理
内存的管理应该对大部分C程序员都不陌生,对指针的内存分配是编程时经常会用到的。内存数据管理有下面几个主要函数:
#include<stdlib.h>
void *malloc(size_t size);
void free(void *ptr_to_memory);
void *calloc(size_t number_of_elements, size_t element_size);
void *realloc(void *exist_memory, size_t newsize);
有一个地方必须注意,有一些系统是用malloc.h文件来调用内存管理程序,我在window下面写C程序时就是用malloc.h这个文件。 malloc()函数会创建大小为size个字节的内存空间,free()函数可以释放内存。这一点可能就是C/C++一直被java取笑的地方,对于内存的处理,内存垃圾都需要程序员去释放处理,而java提供了强大的内存垃圾处理功能,大大减轻程序员的负担。其实这里并没有泼C/C++冷水的意思,只是阐述了C在内存处理方面的不足,但也是它的这种不足,这种面向底层的特点,才让C程序员对整个系统有绝对的控制权。像我们的java老师说过的一句话:能用java实现的东西都能用C实现。这也是C语言多年依旧在语言排行榜上面稳居前三的原因。
扯得有点远了,回到我们的内存处理函数。calloc()与malloc的区别是calloc是用块的思想去分配的,程序员使用元素个数,还有每个元素单元大小去分配内存。本质上是一样的,calloc(n, m) 跟malloc(n*m)的作用是等效的。realloc()相当于先使用free(exist_memory),再malloc(newsize)。因此,使用malloc()跟free()就其实就足以覆盖内存处理的大部分功能了。
文件锁
对于文件的读写操作,有一个很重要的地方我们没提过,那就是读写冲突。假设有一种情况,A、B用户在想读写文件test,把里面的一个变量加1,他们都在对方写入硬盘之前读到变量,结果就造成了写入冲突。本来两个人执行的结果应该是加2,现在变成了加1。程序变得不可预测,所以我们需要去消解这种冲突。
解决文件共享的冲突有两种方法,一种是使用信号量,后面14章会详细地叙述(不过我也不清楚我是否能看到第十四章,哈),另一种是使用文件锁,下面做具体介绍。
#include <fcntl.h>
int fcntl(int fildes, int command, struct flock *flock_structure);
fildes是文件的id,也即是这个函数只能适用于用底层文件操作。
command是一个常量,有三个选项,表示文件锁控制行为
F_GETLK (get lock) 读取文件锁
F_SETLK (set lock) 设置文件锁
F_SETLKW (set lock or wait) 设置文件锁,如果不成功,则等待
struct flock是文件锁的结构体
short l_type; F_RDLCK(读文件锁) F_UNLCK(解锁) F_WRLCK(写文件锁)
short l_whence; SEEK_SET, SEEK_CUR, 或 SEEK_END,参考前面底层文件操作
short l_start; 文件锁起点
short l_len; 文件锁长度
short l_pid; 文件锁进程id
下面有两个例子:
region_1.l_type = F_RDLCK;
region_1.l_whence = SEEK_SET;
region_1.l_start = 10;
region_1.l_len = 20;
res = fcntl(file_desc, F_SETLK, ®ion_1);
对文件10-30字节这个区间增加一个读文件锁
region_2.l_type = F_WRLCK;
region_2.l_whence = SEEK_SET;
region_2.l_start = 40;
region_2.l_len = 10;
res = fcntl(file_desc, F_SETLK, ®ion_2);
对文件40-50字节这个区间增加一个写文件锁。
读文件锁跟写文件锁是不一样的。对于读文件,我们可以允许多个程序同时读,但是此时,写入明显就是不妥的。对于一个进程在写文件时,读写文件都是不允许的,都有可能造成冲突。
要注意的是,文件锁只是返回逻辑判断的结果,而没有真正限制到读写函数本身如何去执行。也即是文件锁提供的只是一个读写冲突的建议,具体如何操作那就要看你程序怎么做了。
dbm数据库
Linux大部分都提供了dbm数据管理工具,这个一个非结构化查询语言(noSQL)。个人感觉它是SQL的雏形,思想上面有挺多地方是一致的。
dbm数据管理的思想是给数据建立索引,做数据查询时可以通过索引去查询,而不是完全扫描整行记录。并且,系统把插入跟查询都给封装起来,让用户跟方便检索。
struct datum {
void *dptr; //数据指针
size_t dsize; //数据长度
};
#include <gdbm-ndbm.h> /* 有些系统使用 #include<ndbm.h> */
DBM *dbm_open(const char *filename, int file_open_flags, mode_t file_mode); 创建
int dbm_store(DBM *database_descriptor, datum key, datum content, int store_mode)
插入数据,key存储的是索引,content是存储数据。
datum dbm_fetch(DBM *database_descriptor, datum key); 检索,key对应索引数据
void dbm_close(DBM *database_descriptor) 关闭
对于DBM类型的创建,跟文件创建是相似的,我就不多说了。
数据的存储有一个参数,store_mode,控制着存储行为的处理。当值为store_insert,遇到索引重复时也会插入数据;当值为store_replace时,遇到索引重复时会直接替代,而不是插入一条新数据。因此,这个函数也可以用来更新数据,功能跟MYSQL的update类似。
对于文件的编译,由于引入了一些库,所以要加一些选项跟参数。
编译 dbm1.c这个文件的例子:
使用ndbm.h库的用户:
gcc –o dbm1 –I/usr/include/gdbm dbm1.c –lgdbm
使用gdbm-ndbm.h库的用户:
gcc –o dbm1 –I/usr/include/gdbm dbm1.c –lgdbm –lgdbm_compat
上面就是我关于数据管理一章的一些总结,说得不对的地方,还请大家多多指出。
- Beginning Linux Programming 笔记(七)数据管理
- Beginning Linux Programming 笔记(五)终端
- Beginning Linux Programming 笔记(四)Linux编程环境
- Beginning Linux Programming 笔记(一) 新的开始
- Beginning Linux Programming 笔记(二) shell编程
- Beginning Linux Programming 笔记(三) 文件处理
- 《Beginning Linux Programming》读书笔记(二)
- 《Beginning Linux Programming》读书笔记(四)
- 《Beginning Linux Programming》读书笔记(三)
- 《Beginning Linux Programming》读书笔记(二)
- 《Beginning Linux Programming》读书笔记(一)
- 《Beginning Linux Programming》读书笔记(序)
- Beginning Linux Programming
- Beginning Linux Programming 笔记(六)使用curses管理基于文本的终端
- Beginning Linux Programming, Third Edition
- Beginning Linux Programming Third Edition
- Beginning Linux Programming chapter 3
- Beginning Linux Programming chapter 4
- 购物兔发布最新版本1.0.7.40
- 不合理且霸道的csdn
- BW: 在Infoset中使用Read Master Data
- SpeedTree学习笔记
- 模拟银行排队叫号机 2011.04.18
- Beginning Linux Programming 笔记(七)数据管理
- 开发人员必备工具:NLiteMapper
- 在北师大演讲《跟我一起创业》
- 20110418
- Java中static修饰一段代码,实现加载时运行的用法
- Red Hat下安装ethereal
- tab标签页
- Ghostscript常见问题
- 命名参数