Будет минимизирована работа с символическими ссылками

Это связано с тем, что flock() может потерпеть неудачу не только потому, что замок уже получен где-то в другом месте. В таком случае он не блокирует ожидание блокировки, но сразу же возвращает false. Другими словами, с помощью LOCK_NB, если flock возвращает false и willblock = 1, значит, он попытался получить блокировку, но он уже получен где-то в другом месте. Но если flock с LOCK_NB возвращает false и beblock = 0, то это означает, что что-то действительно плохое происходит, и стая даже не рассматривала возможность ожидания блокировки, поскольку это было совершенно невозможно.

Проверьте этот код ( здесь также gist ):


Также, чтобы устранить любую путаницу будущих читателей, стоит отметить, что проверка EWOULDBLOCK имеет смысл только для flock () с флагом LOCK_NB, так как в режиме блокировки это либо успех, либо блок или сбой, и никакой блок.

Вы можете подтвердить это, посмотрев на php исходный код для flock :

PHPAPI int php_flock(int fd, int operation)
#if HAVE_STRUCT_FLOCK /* {{{ */
{
    struct flock flck;
    int ret;

    flck.l_start = flck.l_len = 0;
    flck.l_whence = SEEK_SET;

    if (operation & LOCK_SH)
        flck.l_type = F_RDLCK;
    else if (operation & LOCK_EX)
        flck.l_type = F_WRLCK;
    else if (operation & LOCK_UN)
        flck.l_type = F_UNLCK;
    else {
        errno = EINVAL;
        return -1;
    }

    ret = fcntl(fd, operation & LOCK_NB ? F_SETLK : F_SETLKW, &flck);

    if (operation & LOCK_NB && ret == -1 && 
            (errno == EACCES || errno == EAGAIN))
        errno = EWOULDBLOCK;

    if (ret != -1) ret = 0;

    return ret;
}

EWOULDBLOCK установлен только в том случае, если operation & LOCK_NB && ret == -1 && (errno == EACCES || errno == EAGAIN).

Если вас больше интересует реализация, вы также можете прочитать man fcntl , в основном части о F_SETLK и F_SETLKW:

F_SETLK

Получить блокировку (когда l_type - F_RDLCK или F_WRLCK) или освободить блокировку (когда l_type - F_UNLCK) в байтах, заданных полями l_whence, l_start и l_len блокировки. Если конфликтующая блокировка удерживается другим процессом, этот вызов возвращает -1 и устанавливает errno в EACCES или EAGAIN.

F_SETLKW

Что касается F_SETLK, но если конфликтующая блокировка сохраняется файл, затем дождитесь, когда этот замок будет выпущен. Если сигнал улавливается во время ожидания, то вызов прерывается и (после возврата обработчика сигнала) возвращается немедленно (с возвращаемым значением -1 и errno, установленным в EINTR).

blockquote>

0
задан user1032531 25 February 2015 в 15:37
поделиться