【转】进程间通信实例5> 读写者锁的用法
2011-06-01 14:31
246 查看
本文转自: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; } |
相关文章推荐
- C#中Predicate<T>与Func<T, bool>泛型委托的用法实例
- C#中Predicate<T>与Func<T, bool>泛型委托的用法实例
- jQuery中:gt选择器用法实例
- jQuery中:gt选择器用法实例
- linux服务器配置实例<5>---配置Linux防火墙
- Python进程间通信用法实例
- Android实战简易教程<三十>(实例解析Application的用法)
- 数据库 insert 用法实例<二>
- Android实战简易教程<八>(ImageSwitcher用法实例)
- Python进程间通信用法实例
- 大话西游之Office应用实例系列! <5>
- Android实战简易教程<五十八>(AlarmManager类用法研究小实例)
- Yii框架form表单用法实例
- js中setTimeout()与clearTimeout()用法实例浅析
- UNIX网络编程学习(9)--getsockname和getpeername的用法及实例(转)
- PHP中file_get_contents高級用法实例
- Python多进程并发(multiprocessing)用法实例详解
- OpenCV学习之CvMat的用法详解及实例
- Linux下find 命令用法详解+实例
- android中<include />标签的用法