Какая логика работы таймаута в Mutex?

Общие вопросы по использованию второй версии фреймворка. Если не знаете как что-то сделать и это про Yii 2, вам сюда.
Ответить
buba
Сообщения: 26
Зарегистрирован: 2017.01.05, 13:42

Какая логика работы таймаута в Mutex?

Сообщение buba »

Мне нужно обновлять баланс пользователей. Чтобы не было неожиданностей использую mutex, но не могу проверить действие timeout. Или не понимаю логику работы мьютекса.

Вот код

config.php

Код: Выделить всё

'mutex' => [
            'class' => 'yii\mutex\FileMutex',
            'mutexPath' => '@console/runtime/mutex',
        ],
test.php

Код: Выделить всё

$mutex_id = 'test';
        $mutex_timeout = 5;

        if ( \Yii::$app->mutex->acquire($mutex_id, $mutex_timeout) )
        {
            //ждём 20 сек
            sleep(20);

            //разлочим
            \Yii::$app->mutex->release($mutex_id);
            exit('Work');
        }
        else{
            exit('Is running...');
        }
Если запускаю test.php то через 20 сек. получаю Work. Если запускаю test.php и тут же еще один экземпляр test.php, то получу два раза Work через 20 и 20+ секунд.

Я ожидаю, что второй экземпляр (если его запустить сразу за первым) вернет мне Is running... через 5 секунд ($mutex_timeout), типа устал ждать освобождения мьютекса. Но таймаут не наступает.

Что я делаю не так?
skynin
Сообщения: 400
Зарегистрирован: 2017.12.12, 10:09

Re: Какая логика работы таймаута в Mutex?

Сообщение skynin »

первый acquire($mutex_id, $mutex_timeout) сразу захватил мьютекс и продолжил работу
второй попытался, и ждет пока первый освободит мьютекс
первый отпускает, второй сразу захватывает и продолжает работу
третий попытался захватить, и но второй еще не освободил

другими словами - мьютекс это средство монопольного запуска блока кода, в каждый момент времени один и только один может его держать.
и пока не отдаст, все кому он тоже нужен - будут ждать

Мью́текс (англ. mutex, от mutual exclusion — «взаимное исключение») — аналог одноместного семафора, служащий в программировании для синхронизации одновременно выполняющихся потоков.

Мьютекс отличается от семафора тем, что только владеющий им поток может его освободить, т.е. перевести в отмеченное состояние.
https://ru.wikipedia.org/wiki/Мьютекс

-- Я ожидаю, что второй экземпляр (если его запустить сразу за первым
acquire() public method

Acquires a lock by name.
public boolean acquire ( $name, $timeout = 0 )
$name string

Of the lock to be acquired. Must be unique.
$timeout integer

Time (in seconds) to wait for lock to be released. Defaults to zero meaning that method will return false immediately in case lock was already acquired.
Не желайте странного, и не будет у вас головной боли чтобы достичь этого странного.
Тем более что окажется что оно вам и не нужно было, странное это.
buba
Сообщения: 26
Зарегистрирован: 2017.01.05, 13:42

Re: Какая логика работы таймаута в Mutex?

Сообщение buba »

Так в том-то и дело, что какое время не ставь, false я так и не получаю. Как я понимаю, если timeou=0, то второй экземпляр сразу должен получить false. А если timeout=5, то второй экземпляр должен ждать не более 5 секунд. У меня же получается, что второй экземпляр всегда ждёт, когда первый освободит сущность. Т.е. "will return false immediately" не происходит.
skynin
Сообщения: 400
Зарегистрирован: 2017.12.12, 10:09

Re: Какая логика работы таймаута в Mutex?

Сообщение skynin »

buba писал(а): 2019.11.26, 02:38 Т.е. "will return false immediately" не происходит.
Попробуйте более надежный мьютекс, из реализаций DbMutex
Чтобы исключить проблему с файловой системой
Не желайте странного, и не будет у вас головной боли чтобы достичь этого странного.
Тем более что окажется что оно вам и не нужно было, странное это.
Аватара пользователя
maleks
Сообщения: 1992
Зарегистрирован: 2012.12.26, 12:56

Re: Какая логика работы таймаута в Mutex?

Сообщение maleks »

Там далеко не сложный код, можно продебажить каким путем идет выполнение.
Что то не понял если или все таки баг, который и зарепортить не грех
Ответить