【转】进程间通信实例5> 读写者锁的用法

    技术2022-05-19  26

    本文转自:http://blogold.chinaunix.net/u/22617/showart_215469.html

     

    当两个进程都要读写一个文件的时候, 需要用读写锁。   代码:  

    //具体的细节和原理可以参阅 《unix advanced programming 》 里面 12章 高级I/O, 记录锁一节int lock_reg(int fd, int cmd, int type,off_t offset, int whence, off_t len){    struct flock lock;    lock.l_type = type;    lock.l_start = offset;    lock.l_whence = whence;    lock.l_len = len;        return fcntl(fd,cmd,&lock);}#define read_lock(fd,offset,whence,len) /    lock_reg(fd,F_SETLK, F_RDLCK,offset,whence,len)#define readw_lock(fd,offset,whence,len) /    lock_reg(fd,F_SETLKW, F_RDLCK,offset,whence,len)#define write_lock(fd,offset,whence,len) /    lock_reg(fd,F_SETLK, F_WRLCK,offset,whence,len)#define writew_lock(fd,offset,whence,len) /    lock_reg(fd,F_SETLKW, F_WRLCK,offset,whence,len)#define un_lock(fd,offset,whence,len) /    lock_reg(fd,F_SETLK, F_UNLCK,offset,whence,len)

     

    例子:实现一个函数操作文件:

     

    /**    Read the @job_conf , search the entry same as @job , if yes , update the entry with @job     otherwise append the @job at the end of the @job_conf        flag :     JOB_DEL :     Delete the record in download_job.conf         JOB_UPDATE:     update the record with new DownloadConf structure     return:    0:success    这里要用到writer lock ,表面上是读job_conf ,但是实际上读完之后,就要彻底更新job_conf,所以应视为写操作**/int UpdateJob(const DownloadJob *job ,int flag , const char *job_conf){        FILE *fp = NULL;        FILE *fp_new = NULL;                DownloadJob job_info ;        DownloadJob *job_ptr = &job_info;         int fd = 0;                //ready update the JOB_CONF 's item           fp = fopen(JOB_CONF,"r+");    //其实这里主要是读,但是为了实现独占,所以用r+,配合使用writew_lock()(它要求fd是写打开的)    if(!fp) {        if(flag != JOB_DEL) {            fp = fopen(JOB_CONF,"w");            fd = fileno(fp);            //lockf(fd,F_LOCK,0);            writew_lock(fd,0,SEEK_SET,0);                            fwrite(job,sizeof(DownloadJob),1,fp);            //lockf(fd,F_ULOCK,0);            un_lock(fd,0,SEEK_SET,0);            fclose(fp);        }    }    else {        char buf[128];        int isFound = 0;        memset(buf,'/0',sizeof(buf));                fd = fileno(fp);        //lockf(fd,F_LOCK,0);        //jprintf(" ============================== in UpdateJob function ==============================/n");        //jprintf("UpdateJob is waiting for writer lock /n");        writew_lock(fd,0,SEEK_SET,0);        //sleep(10); //这里仅仅给客户演示 读者写者锁确实奏效而已!测试表明,读写者锁效率非常高!bob 2006-5-4 18:04        //jprintf("UpdateJob has got the writer lock /n");                fp_new = fopen("/etc/job_tmp.conf","w") ;        while(fread((void *)job_ptr,sizeof(DownloadJob),1,fp)) {            //jprintf("in UpdateJob() , %s /n",job_ptr->fullpath_name);                        if(!strcmp(job_ptr->fullpath_name,job->fullpath_name)) {            //    jprintf("job_ptr->fullpath_name = %s , job->fullpath_name = %s/n",job_ptr->fullpath_name,job->fullpath_name);                if(flag == JOB_DEL)                    continue;                else {//                    jprintf("job_ptr size = %u/n",sizeof(*job_ptr));//                    jprintf("job size = %u/n",sizeof(*job));//                    jprintf("job->SambaFullPathName = %s/n",job->SambaFullPathName);                    *job_ptr = *job;                     //job_ptr = job;                    isFound = 1;                }            }//            jprintf("job_ptr->SambaFullPathName = %s/n",job_ptr->SambaFullPathName);            fwrite((void *)job_ptr,sizeof(DownloadJob),1,fp_new);        }        if(!isFound)    //this record is new , I append it at the end of file         {            if(flag != JOB_DEL)                fwrite((void *)job,sizeof(DownloadJob),1,fp_new);        }        //lockf(fd,F_ULOCK,0);        fflush(fp_new);        fclose(fp_new);        sync();        snprintf(buf,sizeof(buf)-1,"cp -f /etc/job_tmp.conf %s",JOB_CONF);        system(buf);        unlink("/etc/job_tmp.conf");                un_lock(fd,0,SEEK_SET,0);        fclose(fp);                    }    sync();    return 0;        }


    最新回复(0)