从多个进程访问文件时出现问题

问题描述 投票:0回答:1

我有一个要求。我需要使用 shell CGI 写入和读取配置文件。 我还有一个 C 程序,它每隔几秒钟就不断读取和修改配置文件。 为了保持数据完整性并防止竞争情况,我尝试使用集群。 但它似乎不起作用,因为 CGI 和 C 程序能够同时读取该文件。 任何帮助或建议都会有帮助!

但是如果我在同一个文件上使用2个c程序。它正在发挥作用。但不适用于 CGI 和 C 程序

这是我正在使用的C程序

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

int main() {
    FILE *file;
    struct flock fl = {0};
    char buff[1000];

    file = fopen("/home/siddusuhaas/sample.conf", "r+");
    if (file == NULL) {
        perror("Error opening file");
        return 1;
    }
    printf("Opened File\n");

    // Set an exclusive lock on the entire file
    fl.l_type = F_WRLCK;
    fl.l_whence = SEEK_SET;
    fl.l_start = 0;
    fl.l_len = 0;

    if (fcntl(fileno(file), F_SETLKW, &fl) == -1) {
        perror("Error locking file");
        fclose(file);
        return 1;
    }
    printf("File Lock Successful\n");

    // Perform operations on the locked file here
    system("lslocks | grep 'bcf.conf'");

    // Read the file contents
    size_t nread = fread(buff, sizeof(char), sizeof(buff) - 1, file);
    if (nread == 0 && !feof(file)) {
        perror("Error reading file");
        fclose(file);
        return 1;
    }
    buff[nread] = '\0'; // Null-terminate the buffer
    printf("Data is %zu\t %.*s\n", nread, (int)nread, buff);
    for (int i = 0; i < 10; i++) {
        system("lslocks | grep 'bcf.conf'");
        sleep(1);
        fseek(file , 0  , SEEK_SET);
        memset(buff, 0, sizeof(buff));
        nread = fread(buff, sizeof(char), sizeof(buff) - 1, file);
        if (nread == 0 && !feof(file)) {
            perror("Error reading file");
            fclose(file);
            return 1;
        }
        buff[nread] = '\0'; // Null-terminate the buffer
        printf("Data is %zu\t %.*s\n", nread, (int)nread, buff);
    }
    fl.l_type = F_UNLCK;
    if (fcntl(fileno(file), F_SETLK, &fl) == -1) {
        perror("Error unlocking file");
        fclose(file);
        return 1;
    }
    printf("File Unlocked Successfully\n");

    fclose(file);
    return 0;
}

这是我的 CGI。

#!/bin/bash

file=/home/siddusuhaas/sample.conf

exec 200>>"$file"
if ! flock -x 200; then
    echo "Unable to acquire lock on file" 
    exit 1
fi

echo "Surprise! The file is locked!" > "$file"

#Release the lock
exec 200>&-
linux file-locking flock fcntl
1个回答
0
投票

要获得快速、简单且不那么脏的解决方案,不需要任何特殊工具,请使用

mkdir
。请参阅这篇文章了解一个简单的示例。

mkdir
很简单且原子 - 如果目录不存在,它会创建一个,然后返回成功,所以你知道你,并且只有你拥有锁。如果它不能这样做,它会返回一个错误,所以你知道你现在无法获得锁。

使用一点代码,您可以让它等待,直到它可以轮流,或者检查是否存在超过一定时间的锁并自动删除它,等等。这也可以让您在两者中应用相同的简单逻辑

 bash
和 C.

最后一个建议 - 在退出时设置陷阱以删除锁定文件。
您应该尽快明确地删除它,但是意外的程序退出应该尽可能地清理掉它们,锁定文件是一个典型的例子,说明为什么人们不应该在一个简单的

 时愉快地使用 
kill -9
 kill
就可以了。

© www.soinside.com 2019 - 2024. All rights reserved.