Chinaunix首页 | 论坛 | 博客
  • 博客访问: 383823
  • 博文数量: 55
  • 博客积分: 1907
  • 博客等级: 上尉
  • 技术积分: 869
  • 用 户 组: 普通用户
  • 注册时间: 2010-11-04 19:30
文章分类

全部博文(55)

文章存档

2011年(32)

2010年(23)

分类: LINUX

2011-05-04 19:18:47

07-数据管理

 

在所有的计算机系统中,内存都是一种稀缺资源,无论有多少内存总是显得不够用。从最早期的操作系统版本开始,UNIX风格的操作系统就以一种非常干净的方式来管理内存,因为LINUX系统实现了X/OPEN规范,所以它也继承了这一点。除了一些特殊的嵌入式程序之外,LINUX应用程序是绝不允许直接访问物理内存的。也许应用程序看起来好像可以这样做,但应用程序看到的只是一个精心控制的假象而已。LINUX提供了内存保护机制,它避免了不同应用程序之间的直接干扰。如果机器被正确配置且有足够的交换空间,LINUX允许应用程序访问比实际物理内存更大的内存空间。

 

与内存分配相关的函数

 

1malloc 函数

  1. #include <stdlib.h>

  2. void *malloc( size_t size );

 

参数描述:

               size: 要分配的内存的大小(单位为字节)。

函数描述:

               返回一个指向内核分配的内存的 void * 型指针。因为 malloc 返回的内存的地址对齐的,所以可以强制类型转换为任何类型。

 

2calloc realloc函数

  

  1. #include <stdlib.h>

  2. void *calloc( size_t number_of_elements, size_t element_size );

参数描述:

                number_of_elements:需要分配的元素个数。

element_size:      需分配元素的类型。

函数描述:

               为结构数组分配内存,其所分配的内存将全部初始化为0。如果 calloc 调用成功,将返回指向数组第一次元素的指针。与 malloc 类似,calloc 调用返回的内存空间也无法保证是连续的内存空间,因此如果你想扩大由 calloc 调用返回的数组,只是通过简单地第二次调用 calloc 并期望第二个调用返回的数组空间紧接着第一次返回的数组空间是不可能实现的。

  1. #include <stdlib.h>

  2. void *realloc( void *existing_memory, size_t size );

参数描述:

              existing_memory: 先前调用 malloccallocrealloc返回的指针。

              size:                     需分配的元素的类型。

函数描述:

               用来改变先前以分配的内存长度。通过 size 参数可以增加或减少其长度,所以realloc 调用可能需要移动数据。因此,在你调用 realloc 改变了内存之后就应该用realloc 返回的新指针去访问内存,而不是用先前的指针去访问,切记。

       

 

3free 函数

  1. #include <stdlib.h>

  2. void free( void *ptr_to_memory );

参数描述:

               ptr_to_memory:先前调用 malloccallocrealloc返回的指针。

函数描述:

                动态使用内存的程序总是应该调用 free 来把不用的内存释放给 malloc 内存管理器。这样做可以将分散的块重新合并到一起,并由 malloc 函数库来管理它,而不是由应用程序来管理。如果一个应用程序(进程)自己使用并释放内存,则这些自由内存实际上仍然处于被分配给进程的状态。

 

 

文件锁定

 

LINUX 提供了多种特性来实现文件锁定。其中最简单的方式就是以原子操作的方式来创建锁文件的技巧。所谓“原子操作”就是在创建锁文件时,系统将不允许任何其他事情的发生。这就给进程提供了一种方式来确保它创建的文件是唯一的,而且这个文件不可能在同一时间被其他程序创建。

 

与锁定区域相关的函数

 

  1. #include <fcntl.h>

  2. int fcntl( int fildes, int command, struct flock *flock_structrure );

 

fcntl 对一个打开的文件描述符操作,并能根据 command 参数的设置完成不同的任务,第三个参数是一个指向 flock 结构的指针。

 

参数描述:

              command 取值如下:

                                           F_GETLK

                                           F_SETLK

                                           F_SETLKW

 

F_GETLK:用来获得 fildes 打开文件的锁信息,它不会尝试去锁定文件。一个进程可能使用 F_GETLK来查看某个区域的当前锁状态。它应该设置flock 结构来表明它可能需要的锁类型并定义它感兴趣的区域。fcntl 调用成功就返回非 -1 的值。如果文件已被锁定从而阻止锁请求成功执行,这时 fcntl 会用有关的信息覆盖 flock 结构,那么我们在应用程序中就可以将这些信息打印出来。如果锁请求成功执行,那么 flock 结构将不会改变。如果 F_GETLK无法获得信息,它将返回 -1 表示失败。如果F_GETLK调用成功(例如,它返回一个非 -1 的值),调用的程序必须检查 flock 结构的内容是否被修改过。因为 l_pid 的值被修改成锁定该区域的进程的进程号,所以通过检查这个字段就可以很方便的判断出 flock 结构是否被修改过。一般在还没有判断前,先将 l_pid 字段设置为 -1

 

F_SETLK fildes 指向的文件的某个区域加锁或解锁。

F_SETLKW:对 fildes 指向的文件的某个区域加锁或解锁,但在无法获取锁时,将等待到

获取到锁为止。

 

flock 结构包含如下成员:

                              short  l_type

                              short  l_whence

                              off_t  l_start

                              off_t  l_len

                              pid_t  l_pid

 

l_type取值如下:

                       F_RDLCK:共享锁(读锁)。

             F_UNLCK:解除锁。

             F_WRLCK:独占锁(写锁)。 

 

l_whence: SEEK_SET(文件头)、SEEK_CUR(当前位置)、SEEK_END(文件尾)。

l_start: 锁区域开始的第一个字节。

l_len:  锁区域的字节数。

l_pid:  持有锁的进程。

 

 

文件死锁

 

假设两个程序希望更新同一个文件。他们需要同时更新字节 1 和字节 2 。程序 A 首先更新字节 2 ,然后再更新字节 1 。程序 B 首先更新字节 1 ,然后再更新字节 2 。现在两个程序同时启动。程序 A 锁定字节 2 而程序 B 锁定字节 1 。然后程序 A 尝试锁定字节1,但因为这时字节 1 已经本程序 B 锁定,所以程序 A 将在那里等待。接着程序 B 尝试锁定字节 2,但因为这个字节已经被程序 A 锁定,所以程序 B 也在那里等待。这种当两个程序都无法执行下去的情况,就被称为死锁(dead lock)或致命拥抱(deadly embrace)。避免死锁的一般方法是:两个程序应该使用相同的顺序来请求锁定他们需要更新的字节,或锁定一个更大的区域。

 

 

阅读(1815) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~