UNIX网络编程——记录上锁

来源:互联网 发布:达内 java培训机构 编辑:程序博客网 时间:2024/05/08 13:10

记录锁是读写锁的一种扩展类型,可用于亲缘关系或无亲缘关系的进程之间共享某个文件的读与写。被锁住的文件通过文件描述符进行访问,执行上锁的操作函数是fcntl,这种类型的锁通常在内核中维护。

  记录锁的功能是:一个进程正在读或修改文件的某个部分时,可以阻止其他进程修改同一文件区,即其锁定的是文件的一个区域或整个文件。记录锁有两种类型:共享读锁,独占写锁。基本规则是:多个进程在一个给定的字节上可以有一把共享的读锁,但在一个给定字节上的写锁只能有一个进程独用。即:如果在一个给定的字节上已经有一把读或多把读锁,则不能在该字节上再加写锁;如果在一个字节上已经有一把独占性的写锁,则不能再对它加任何读锁。

  采用Uinx打印假脱机处理系统举例说明记录锁的作用。打印假脱机处理系统使用技巧是给每台打印机准备一个文件,它只是一个单行执行的ASCII文本文件,其中还有待用的下一个序列号,需要给某个打印作业赋一个序列号的每个进程都得经历以下三个步骤:

(1)读序列号文件

(2)使用其中的序列号

(3)给序列号加1并写回文件中

存在问题:当某个进程在执行这个三个步骤时,另一个进程可能在执行同样的三个步骤,这将导致结果混乱。

解决办法:一个进程能够设置某个锁,以宣称没有其他进程能够访问相应的文件,直到第一个进程完成访问为止。


#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <fcntl.h>#include <errno.h>#define SEQFILE     "seqno"#define FILE_MODE   (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)#define MAXLINE  1024void my_lock(int fd);void my_unlock(int fd);int main(int argc,char *argv[]){    int fd;    long i,seqno;    pid_t pid;    ssize_t  n;    char line[MAXLINE+1];    pid = getpid();    fd = open(SEQFILE,O_RDWR,FILE_MODE);    for(i=0;i<20000;++i)    {        my_lock(fd);        lseek(fd,0L,SEEK_SET);        n = read(fd,line,MAXLINE);        line[n] = '\0';        n = sscanf(line,"%ld\n",&seqno);    //    printf("%s: pid = %ld,seq# = %ld\n",argv[0],(long) pid,seqno);        seqno++;        snprintf(line,sizeof(line),"%ld\n",seqno);        lseek(fd,0L,SEEK_SET);        write(fd,line,strlen(line));        my_unlock(fd);    }    exit(0);}void my_lock(int fd){    struct flock lock;    lock.l_type = F_WRLCK;  //写入锁    lock.l_whence = SEEK_SET; //从文件头开始    lock.l_start = 0;  //锁住整个文件    lock.l_len = 0;    fcntl(fd,F_SETLKW,&lock);}void my_unlock(int fd){    struct flock  lock;    lock.l_type = F_UNLCK; //释放锁    lock.l_whence = SEEK_SET; //从文件头开始    lock.l_start = 0;  //释放整个个文件    lock.l_len = 0;    fcntl(fd,F_SETLK,&lock);}

0 0
原创粉丝点击