【问题标题】:File locking in Linux using C program使用 C 程序在 Linux 中锁定文件
【发布时间】:2012-11-20 07:14:14
【问题描述】:

我想从 c 程序创建一个文件,并且我想在我的 c 二进制文件中使用有点长的时间。但我想以这样的方式创建文件,直到我的 c 程序完成处理文件创建并解锁它之前没有人(可能使用 vim 或任何其他编辑器)能够打开和读取文件内容。

请提前帮我解决这个问题。

【问题讨论】:

标签: filelock


【解决方案1】:

为此,您可以在 Unix 上定义一个强制文件锁。 但是,有必要(重新)挂载文件系统,以便它遵守强制锁。

1 例如重新挂载root fs,使用(作为root):

mount -oremount,mand /

2 现在,让我们创建我们的秘密文件:

echo "big secret" > locked_file

3 我们需要设置-group-id,并禁用文件的组执行权限:

chmod g+s,g-x locked_file

以及我们用于锁定该文件的 C 代码: (代码会锁定文件,并保持锁定一段时间,你可以尝试另一个终端读取它,读取会延迟到锁定释放)

#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>

int main() {

struct flock fl;
int fd;

fl.l_type   = F_WRLCK;  /* read/write lock */
fl.l_whence = SEEK_SET; /* beginning of file */
fl.l_start  = 0;        /* offset from l_whence */
fl.l_len    = 0;        /* length, 0 = to EOF */
fl.l_pid    = getpid(); /* PID */

fd = open("locked_file", O_RDWR | O_EXCL); /* not 100% sure if O_EXCL needed */

fcntl(fd, F_SETLKW, &fl); /* set lock */

usleep(10000000);

printf("\n release lock \n");

fl.l_type   = F_UNLCK;
fcntl(fd, F_SETLK, &fl); /* unset lock */

}

更多信息见 http://kernel.org/doc/Documentation/filesystems/mandatory-locking.txt

【讨论】:

    【解决方案2】:

    可以使用flock() 锁定文件。它的语法是

    #include <sys/file.h>
    #define   LOCK_SH   1    /* shared lock */
    #define   LOCK_EX   2    /* exclusive lock */
    #define   LOCK_NB   4    /* don't block when locking */
    #define   LOCK_UN   8    /* unlock */
    
    int flock(int fd, int operation);
    

    使用 fopen() 或 open() 打开第一个文件。然后使用下面给出的flock() 锁定这个打开的文件

    int fd = open("test.txt","r");
    int lock = flock(fd, LOCK_SH);  // Lock the file . . .
    // . . . .
    // Locked file in use 
    // . . . .
    int release = flock(fd, LOCK_UN);  // Unlock the file . . .
    

    【讨论】:

      【解决方案3】:

      我喜欢第一个答案(简短而甜美),但它在 CentOS-7 上的 gcc 无法正常工作。这个小技巧满足了我使用涉及 procmail 的小应用程序的需求(注意:如果您正在更新数据文件内容,请确保在释放锁之前调用 fflush。否则,跳过锁释放并调用 fclose,因为它看起来那个时候锁就被解除了)

      #include <stdio.h>
      #include <stdlib.h>
      #include <errno.h>
      #include <sys/file.h>
      //
      #define LOCK_SH 1   // shared lock
      #define LOCK_EX 2   // exclusive lock
      #define LOCK_NB 4   // don't block when locking
      #define LOCK_UN 8   // unlock
      extern int errno;   // this is located elsewhere
      //
      void debug(int rc){
          if ((rc>0)||(errno>0)){
          printf("rc: %d err: %d\n", rc, errno);
              errno = 0;  // clear for next time
          }
      }   
      //
      void main(){
          FILE *fp;
          int rc;
          //
          printf("fopen\n");
          fp = fopen("flock_demo.dat","r+");
          if (fp == NULL){
              printf("err: %d\n", errno);
          perror("-e-cannot open file");
          exit(2);
          }
          printf("flock\n");
          rc = flock( fileno(fp), LOCK_EX );
          debug(rc);
          printf("now run this program on another session\n");
          printf("then hit <enter> to continue");
          getchar();
          printf("\n");
          printf("funlock\n");
          rc = flock( fileno(fp), LOCK_UN );
          debug(rc);
          printf("fclose\n");
          rc = fclose(fp);
          debug(rc);
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-09-15
        • 2021-03-29
        • 1970-01-01
        • 2014-02-09
        • 1970-01-01
        • 1970-01-01
        • 2012-09-14
        相关资源
        最近更新 更多