Страницы

Поиск по вопросам

четверг, 2 января 2020 г.

Блокирование и разблокировка файла

#cpp #c #файлы #lock_free #flock


Есть программа, которая перезаписывает некоторый файл. И есть другая программа, которая
периодически считывает данные из файла. Однако, чтобы читающая программа всегда получала
верные данные, нужно блокировать файл, пока он не запишется до конца. Есть такой код
для записи файла с блокировкой:

int Writer()
{
    int iErrorCode = 0;
    char pcStr[] = "I am string, that must be written to file.";

    int iTry = 0;
    int iMaxTry = 10;

    struct flock lck;
    lck.l_type = F_WRLCK; /*setting a write lock*/
    lck.l_whence = 0;     /*offset l_start from beginning of file*/
    lck.l_start = 0l;
    lck.l_len = 0l;       /*until the end of the file address space*/

    int fd;   /*file descriptor*/
    fd = open("outfile.txt", O_RDWR);
    if (fd < 0) {
        perror("outfile.txt");
        return 1;
    }

    while (fcntl(fd, F_SETLK, &lck) < 0) {
        if (errno == EAGAIN || errno == EACCES) {
            if (++iTry < iMaxTry) {
                sleep(2);
                continue;
            }
            (void) fprintf(stderr, "File is bisy.");
        }
    }

    size_t read_bytes;
    size_t written_bytes;
    size_t szContentLen = strlen(pcStr);
    char *buffer = new char[szContentLen];
    strcat(buffer, pcStr);
    while ((read_bytes = read (fd, buffer, szContentLen)) > 0)
    {
        /* 1 == stdout */
        written_bytes = write (1, buffer, read_bytes);
        if (written_bytes != read_bytes)
        {
            fprintf (stderr, "Cannot write\n");
            return 2;
        }
    }
    if (close (fd) != 0)
    {
        fprintf (stderr, "Cannot close file (descriptor=%d)\n", fd);
        return 3;
    }

    return iErrorCode;
}


Как разблокировать данный файл после окончания записи, чтобы другая программа, которая
захочет читать из файла, имела доступ к нему?
    


Ответы

Ответ 1



Разблокировать файл после окончания записи можно так же, как вы его блокировали, только параметр в структуре поменять: lck.l_type = F_UNLCK; /*unlock file */ lck.l_whence = 0; /*offset l_start from beginning of file*/ lck.l_start = 0l; lck.l_len = 0l; /*until the end of the file address space*/ fcntl(fd, F_SETLK, &lck);

Комментариев нет:

Отправить комментарий