1. 程式人生 > >fcntl函式對檔案鎖的操作

fcntl函式對檔案鎖的操作

在Shell下輸入man fcntl可獲取函式原型

#include <unistd.h> #include<fcntl.h> int fcntl( int fd, int cmd , struct flock *lock); 這裡,fd表示開啟檔案的檔案描述符 cmd在這裡可取F_SETLK 設定或釋放鎖;F_GETLK 獲取鎖的屬性 struct flock {     short l_type;     short l_whence;
    off_t l_start;     off_t l_len;     pid_t l_pid; }; 程式碼如下:

#include<stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <fcntl.h>
#include<string.h>
int lock_set(int fd,struct flock *lock)
{
   if (fcntl(fd,F_SETLK,lock)==0)
   { 
      if (lock->l_type==F_RDLCK)
       {
         printf("set read lock,pid:%d\n",getpid());
       }
     else if (lock->l_type==F_WRLCK)
       {
         printf("set wirte lock,pid:%d\n",getpid());
       }
    else if (lock->l_type==F_UNLCK)
       {
         printf("release lock,pid:%d\n",getpid());
       }
   }
   else
   {
      perror("lock operation failed\n");
      return -1;
   }
   return 0;
}
int lock_test(int fd, struct flock *lock)
{
   if (fcntl(fd,F_GETLK,lock)==0)
   {
      if (lock->l_type==F_UNLCK)
      {
         printf("lock can be set in fd\n");
         return 0;
      } 
      else 
      {
         if (lock->l_type==F_RDLCK)
         {
         printf("can't be set,read lock has been set by:%d\n",lock->l_pid);
         } 
         else if (lock->l_type==F_WRLCK)
         {
         printf("can't be set,write lock has been set by:%d\n",lock->l_pid);
         } 
        return -2;
      } 
   }
   else
   {
      perror("get lock failed");
      return -1;
   }
}
int main()
{
   int fd;
    char buf[64]="Hello World!";
     char read_buf[64];
    struct flock lock;
    memset(read_buf,0,64);
   if ((fd=open("lala.c",O_CREAT|O_TRUNC|O_RDWR,S_IRWXU))==-1)
    {
       perror("open fail");
       return 1;
    }
    write(fd,buf,strlen(buf));
     memset(&lock,0,sizeof(struct flock));
     lock.l_start=SEEK_SET;
     lock.l_len=0;
      lock.l_whence=0;
     lock.l_type=F_RDLCK;
     if(lock_test(fd,&lock)==0)
      {
          lock.l_type=F_RDLCK;
          lock_set(fd,&lock);
      }
     close (fd);
    return 0;
}