【转】进程间通信实例5> 读写者锁的用法
来源:互联网 发布:软件腰带图片 编辑:程序博客网 时间:2024/05/23 23:14
本文转自: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;
}
- 【转】进程间通信实例5> 读写者锁的用法
- Linux进程间通信::读写特性和匿名管道的应用(协同进程实例)
- 进程间通信系列(一)管道读写实例
- 进程间通信系列(一)管道读写实例
- 进程间通信系列(一)管道读写实例
- 【转】 进程间的通信(互斥锁、条件变量、读写锁、文件锁、信号灯)
- 进程通信之读写锁
- 基于Message的进程间通信实例
- 进程间通信---AIDL的使用实例
- 进程间通信---AIDL的使用实例
- 进程间通信时读写阻塞的条件
- python 多进程实例 进程间的通信
- 通过互斥量和读写锁来实现进程间通信
- 进程间通信学习笔记-互斥锁 && 读写锁
- 进程间的通信(互斥锁、条件变量、读写锁、文件锁、信号灯)
- 进程间的通信(互斥锁、条件变量、读写锁、文件锁、信号灯)
- 进程间的通信(互斥锁、条件变量、读写锁、文件锁、信号灯)
- 进程间的通信(互斥锁、条件变量、读写锁、文件锁、信号灯)
- 【转】fcntl 函数介绍
- 一般处理程序中使用注意事项
- .net程序员必须学习的10项技术
- Linux 文件类型、文件扩展名、文件系统
- mybatis 初学 小例子
- 【转】进程间通信实例5> 读写者锁的用法
- eclipse spring xml 无提示解决
- HttpUtil
- struts返回( return)的问题
- 寻找素数
- 【转】Linux线程同步(3): 读写锁(rwlock)
- android map
- WD align
- row_number()