linux文件读写 文件锁、select、poll【转】
本文转载自:http://blog.csdn.net/fansongy/article/details/6853395
一、文件锁
    文件锁用于多个用户共同使用或操作同一个文件。有读锁的时候可以再加读锁,不能再加写锁。有写锁的时候,不能加任何锁,加读锁时,该描述符必须是读打开,加写锁时,该描述符必须是写打开,且只在进程间有用。     
 
 重写的上锁方法
[cpp] view plain copy print?
//lock.c  
int lock_set(int fd,int type){  
    struct flock lock;  
  
    lock.l_type=type;  
    lock.l_start=0;  
    lock.l_whence=SEEK_SET;  
    lock.l_len = 0;  
    lock.l_pid=-1;  
  
    fcntl(fd,F_GETLK,&lock);  
    if(lock.l_type!=F_UNLCK){  
        if(lock.l_type == F_RDLCK)  
            printf("Read lock already set by %d!\n",lock.l_pid);  
        else if(lock.l_type == F_WRLCK)  
            printf("Write lock already set by %d!\n",lock.l_pid);  
    }  
    lock.l_type = type;  
    //此处的F_SETLKW为F_SETLK的阻塞版本,当无法获取锁时进入睡眠等待状态  
    if(fcntl(fd,F_SETLKW,&lock)<0){  
        printf("Lock failed:type=%d!\n",lock.l_type);  
        exit(1);  
    }  
  
    switch(lock.l_type){  
        case F_RDLCK:  
            printf("read lock set by %d\n",getpid());  
            break;  
        case F_WRLCK:  
            printf("write lock set by %d\n",getpid());  
            break;  
        case F_UNLCK:  
            printf("UN lock set by %d\n",getpid());  
            break;  
        default:  
            break;  
    }  
}  
上写锁
[cpp] view plain copy print?
#include  
#include  
#include  
#include"lock.c"  
  
int main(){  
    int fd;  
    fd=open("readme",O_RDWR|O_CREAT,0666);  
    if(fd<0){  
        printf("Open file error\n");  
        exit(1);  
    }  
    lock_set(fd,F_WRLCK);  
    getchar();  
    lock_set(fd,F_UNLCK);  
    getchar();  
    return 0;  
  
}  
上读锁
[cpp] view plain copy print?
#include  
#include  
#include  
#include"lock.c"  
  
int main(){  
    int fd;  
    fd=open("readme",O_RDWR|O_CREAT,0666);  
    if(fd<0){  
        printf("Open file error\n");  
        exit(1);  
    }  
    lock_set(fd,F_RDLCK);  
    getchar();  
    lock_set(fd,F_UNLCK);  
    getchar();  
    return 0;  
  
}  
在两个终端中测试:
两个终端可以同时加上读锁。
有一个终端加上读锁,则必须等读锁释放才能加写锁。
有一个终端加写锁必须释放才能加别的锁。
 
二、多路复用:select、poll
[cpp] view plain copy print?
#include  
#include  
#include  
#include  
#define MAX(a,b) (a>b?a:b)  
  
int main(){  
    int fd[3];  
    char buff[1024];  
    int res,max_fd,i,num;  
    fd_set insert,temp_insert;  
    struct timeval tv;  
    fd[0]=0;  
    if((fd[1]=open("in1",O_RDONLY|O_NONBLOCK))<0){  
        printf("open in1 error!\n");  
        return 1;  
    }  
    if((fd[2]=open("in2",O_RDONLY|O_NONBLOCK))<0){  
        printf("open in2 error!\n");  
        return 1;  
    }  
    //选出最大的fd,select()函数用的  
    max_fd=MAX(MAX(fd[0],fd[1]),fd[2]);  
    //清空fd_set  
    FD_ZERO(&insert);  
    for(i=0;i<3;i++){  
        FD_SET(fd[i],&insert);  
    }  
    //设置延迟  
    tv.tv_sec=60;  
    tv.tv_usec=0;  
  
    while(FD_ISSET(fd[0],&insert) || FD_ISSET(fd[1],&insert) || FD_ISSET(fd[2],&insert)){  
        temp_insert = insert;  
        //select函数会对fd_set产生修改,只保存变化的文件符,所以要用一个temp  
        res=select(max_fd+1,&temp_insert,NULL,NULL,&tv);  
        switch(res){  
            case -1:  
                    printf("select error!\n");  
                    return 1;  
                    break;  
            case 0:  
                    printf("time out\n");  
                    return 1;  
                    break;  
            default:  
                    for(i=0;i<3;i++){  
                        if(FD_ISSET(fd[i],&temp_insert)){  
                                memset(buff,0,1024);  
                                num=read(fd[i],buff,1024);  
                                if(num<0){  
                                    return 1;  
                                }else if(num == 0){  
                                    close(fd[i]);  
                                    FD_CLR(fd[i],&insert);  
                                }else{  
                                    if(i == 0){  
                                        if((buff[0] == 'q') || (buff[0] == 'Q')){  
                                            return 0;  
                                        }  
                                    }  
                                    write(STDOUT_FILENO,buff,num);  
  
                                }  
                        }  
                    }  
            }  
    }  
}  
 
poll用法与select很相似,只是在一些变量上有些不同:
 
[cpp] view plain copy print?
#include   
#include   
#include   
#include   
#include   
#include   
#include   
  
#define MAX_BUFFER_SIZE 1024  
#define IO_IN_FILES 3  
#define TIME_DELAY 60000  
  
int main() {  
    struct pollfd fds[IO_IN_FILES];  
    char buff[MAX_BUFFER_SIZE];  
    int i,res,real_read;  
  
    fds[0].fd=0;  
    if((fds[1].fd=open("in1",O_RDONLY|O_NONBLOCK))<0) {  
        printf("Open in1 error!\n");  
        return 1;  
    }  
      
    if((fds[2].fd=open("in2",O_RDONLY|O_NONBLOCK))<0) {  
        printf("Open in2 error!\n");  
        return 1;  
    }  
  
    for(i=0;i                 
 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号