Linux程序设计第七章

来源:互联网 发布:编程时说a having been 编辑:程序博客网 时间:2024/05/16 17:11
今天抽空去跟人凑热闹,参加了一下招聘,反正都是玩,结果一大堆图形学的题目,对图形学哪有研究过啊。真是让我汗流浃背啊。没办法,人家公司就是做视频监控和图像处理的,可以理解。人生第一投啊,就这么打酱油了。
        今天,学习linux程序设计第七章。
本章讲的是数据管理。
7.1 内存管理
linux使用标准C语言的malloc来调用来简单实现内存分配,至于内核的实现,这个目前就不关注了。~~

7.2文件锁定
1.创建锁文件,可以用ftntl.h里面定义的open调用,同时带上O_CREAT和O_EXCL标志.
2.如果要对文件的某个区域进行锁定.linux提供了至少两种方式来实现这些.一是使用系统fcntl,二是使用lockf调用.因为这两种不能同时工作,在底层使用着不同的实现.所以主要坚持使用一种就好.这里学习的是fcntl调用.fcntl的函数原型
#include<fcntl.h>
int fcntl(int fildes,int command,strucct flock *flock_structure);
其中最后一个参数是一个文件锁结构。
3.文件锁定状态下的读写操作,不要使用fread或fwrite这种库函数,而要使用read和write这种系统调用。,主要是库函数会预读出比你所要的字符更多的内容,放在缓冲区里面。比如说,文件有100行,A读出50行,使用库函数,将会把整个文件读出来,这个时候,如果后50行被更改了,但是却没有及时更新自己的文件,所以要使用read和write系统调用来实现读写操作。这里给出事例来看看具体文件锁的工作情况。

这是其中lock3.c 的代码
 ************************************************************************/
#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>
#include<fcntl.h>

const char *test_file = "/tmp/test_lock";

int main()
{
    int file_desc;
    int byte_count;
    char *byte_to_write = "A";
    struct flock region_1;
    struct flock region_2;
    int res;

    file_desc = open(test_file,O_RDWR|O_CREAT,0666);
    if(!file_desc)
    {
        fprintf(stderr,"unalbe to open %s for read/write \n",test_file);
        exit(EXIT_FAILURE);

    }

    for(byte_count = 0; byte_count < 100;byte_count++)
    {
        (void)write(file_desc,byte_to_write,1);
    }

    region_1.l_type = F_RDLCK;
    region_1.l_whence = SEEK_SET;
    region_1.l_start = 10;
    region_1.l_len = 20;

    region_2.l_type = F_WRLCK;
    region_2.l_whence = SEEK_SET;
    region_2.l_start = 40;
    region_2.l_len = 10;


    printf("Process %d locking file\n",getpid());
    res = fcntl(file_desc,F_SETLK,&region_1);
    if(res == -1)
        fprintf(stderr,"Failed to lock region 1\n");
    res = fcntl(file_desc,F_SETLK,&region_2);
    if(res == -1)
        fprintf(stderr,"Failed to lock region 2\n");

    sleep(60);

    printf("Process %d closeing file \n",getpid());
    close(file_desc);
    exit(EXIT_SUCCESS);
}

这是lock4.c的代码

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<fcntl.h>

const char *test_file = "/tmp/test_lock";

#define SIZE_TO_TRY 5

void show_lock_info(struct flock *to_show);

int main()
{
    int file_desc;
    int res;
    struct flock region_to_test;
    int start_byte;

    file_desc = open(test_file,O_RDWR | O_CREAT,0666);
    if(!file_desc)
    {
        fprintf(stderr,"error\n");
        exit(EXIT_FAILURE);
   
    }

    for(start_byte = 0 ; start_byte < 99;start_byte += SIZE_TO_TRY)
    {
        region_to_test.l_type = F_WRLCK;
        region_to_test.l_whence = SEEK_SET;
        region_to_test.l_start = start_byte;
        region_to_test.l_len = SIZE_TO_TRY;
        region_to_test.l_pid = -1;

        printf("Testing F_WRLCK on region from %d to %d \n",start_byte,start_byte+SIZE_TO_TRY);

        res = fcntl(file_desc,F_GETLK,&region_to_test);

        if(res == -1)
        {
            fprintf(stderr,"get faild\n");
            exit(EXIT_FAILURE);
        }

        if(region_to_test.l_pid != -1)
        {
            printf("Lock would fail.F_GETLK returned :\n");
            show_lock_info(&region_to_test);
        }
        else
        {
            printf("succeed\n");
        }


        region_to_test.l_type = F_RDLCK;
        region_to_test.l_whence = SEEK_SET;
        region_to_test.l_start = start_byte;
        region_to_test.l_pid = -1;
        printf("Testing F_RDLCK on region from %d to %d\n",start_byte,start_byte+SIZE_TO_TRY);

        res = fcntl(file_desc,F_GETLK,&region_to_test);


        if(res == -1)
        {
            fprintf(stderr,"get faild\n");
            exit(EXIT_FAILURE);
        }

        if(region_to_test.l_pid != -1)
        {
            printf("Lock would fail.F_GETLK returned :\n");
            show_lock_info(&region_to_test);
        }
        else
        {
            printf("succeed\n");
        }

    }
   
    close(file_desc);
    exit(EXIT_FAILURE);

}

void show_lock_info(struct flock *to_show)
{
    printf("\tl_type %d ,",to_show->l_type);
    printf("l_whence %d ,",to_show->l_whence);
    printf("l_start %d ,",(int)to_show->l_start);
    printf("l_len %d ,",(int)to_show->l_len);
    printf("l_pid %d\n",to_show->l_pid);
}
其中我们先在运行lock3,比如说./lock3 &
之后执行lock4可以看到一系列输出,其中lock3对文件中的一些区段加了共享锁,而对一些另外的区段加了独占锁.运行lock4可以发现,在加了共享锁的情况下,我们可以获得该共享锁,但是若要对它添加独占锁,则会出错.文件被加了独占锁的区域,不管任何锁都不能再被设置.空白区域,则接受这两种锁的任意设置.

4.文件锁的竞争,
其实就是共享锁允许再加共享锁,独占锁不允许再加任何锁.共享锁允许程序解锁,但是成功与否取决于是否对文件再次进行加锁(比如:原本存在共享锁,你给它解锁,然后尝试加上独占锁,将会出错).如果你没有办法在某个时间段获得文件锁,你可以调用F_SETLKW来等待,直到你能获取该锁.
其实还有一种更为简单的lockf接口,但是我们就不去研究他了.坚持使用一种就好了.其实我也不知道作者为什么不对这种更简单的方法做介绍,可能是认为系统调用更加原生态吧.
死锁我们就不讨论了,大家都懂的.

7.3数据库
dbm数据库

今天头好痛,不想在看这个了。早点回去休息吧。到时候,用到的话,我会在回来看的。。

最后,预祝各位学长们,找到一份好工作。加油。



原创粉丝点击