Временный блокировщик
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 04.02.24 07:07
Оценка:
Здравствуйте!


Где-то в каком-то потоке периодически что-то производится, какие-то действия. Иногда надо временно запретить их производить.

В других потоках, или в том же потоке, можно запрещать, рекурсивно, главное, разлочить столько же раз, сколько и залочил.

Что-то городить с какими-то примитивами синхронизации не вижу смысла, ну, может я ошибаюсь.

Пока придумалась такая схема (псевдокод):

class Locable
{
   std::atomic<bool>  m_lock;

public:
   void lock();
   void unlock();
   bool isLocked() const;
};

// Где-то в цикле что-то периодически делается

if (!locablePermitter.isLocked())
{
    doSomething();
}

// Тут ведём подсчет количества блокировок

class Locker
{
    std::atomic<int>  m_counter;
    Locable          *m_pLocable;

public:

    void lock()
    {
        if (++m_counter > 0)
        {
            m_pLocable->lock();
        }
    }

    void lock()
    {
        if (--m_counter <= 0)
        {
            m_pLocable->unlock();
        }
    }

};



Ну или как лучше сделать? Может, есть что-то стандартное, чем изобретать велосипеды?
Маньяк Робокряк колесит по городу
Re: Временный блокировщик
От: andrey.desman  
Дата: 04.02.24 07:16
Оценка:
Здравствуйте, Marty, Вы писали:


M>Где-то в каком-то потоке периодически что-то производится, какие-то действия. Иногда надо временно запретить их производить.


Просто пропустить, вывешивать в ожидание не надо?

M>Пока придумалась такая схема (псевдокод):

M>Ну или как лучше сделать? Может, есть что-то стандартное, чем изобретать велосипеды?

Если тормозить поток на нем не надо, то такая схема ок. Разве что два атомика тут лишние. Один класс lockable со счетчиком, лочить через std::lock_guard.
Re[2]: Временный блокировщик
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 04.02.24 07:23
Оценка:
Здравствуйте, andrey.desman, Вы писали:

M>>Где-то в каком-то потоке периодически что-то производится, какие-то действия. Иногда надо временно запретить их производить.


AD>Просто пропустить, вывешивать в ожидание не надо?


Да, именно так


M>>Пока придумалась такая схема (псевдокод):

M>>Ну или как лучше сделать? Может, есть что-то стандартное, чем изобретать велосипеды?

AD>Если тормозить поток на нем не надо, то такая схема ок. Разве что два атомика тут лишние. Один класс lockable со счетчиком, лочить через std::lock_guard.


Лишний атомик в булевском флаге, я правильно понял?
Маньяк Робокряк колесит по городу
Re[2]: Временный блокировщик
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 04.02.24 07:25
Оценка:
Здравствуйте, andrey.desman, Вы писали:

AD>Просто пропустить, вывешивать в ожидание не надо?


Ну и я, наверное, не совсем правильно тут использовал слова на базе lock, может как-то по другому назвать?
Маньяк Робокряк колесит по городу
Re: Временный блокировщик
От: andrey.desman  
Дата: 04.02.24 07:25
Оценка:
Здравствуйте, Marty, Вы писали:

M>Где-то в каком-то потоке периодически что-то производится, какие-то действия. Иногда надо временно запретить их производить.


Хотя не понятно, что значит запрещать? Если поток уже что-то делает запрещенное, а ты запретил, это будет ок? Или нужна критсекция все-таки?
Наверное тебе подойдет std::shared_mutex.
Re: Временный блокировщик
От: vopl Россия  
Дата: 04.02.24 07:26
Оценка:
Здравствуйте, Marty, Вы писали:

M>Ну или как лучше сделать? Может, есть что-то стандартное, чем изобретать велосипеды?


У тебя получился Семафор
Re[2]: Временный блокировщик
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 04.02.24 07:27
Оценка:
Здравствуйте, andrey.desman, Вы писали:

AD>Здравствуйте, Marty, Вы писали:


M>>Где-то в каком-то потоке периодически что-то производится, какие-то действия. Иногда надо временно запретить их производить.


AD>Хотя не понятно, что значит запрещать? Если поток уже что-то делает запрещенное, а ты запретил, это будет ок?


Нормас, главное, чтобы потом в следующий раз пропустил
Маньяк Робокряк колесит по городу
Re[2]: Временный блокировщик
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 04.02.24 07:29
Оценка:
Здравствуйте, vopl, Вы писали:

M>>Ну или как лучше сделать? Может, есть что-то стандартное, чем изобретать велосипеды?


V>У тебя получился Семафор



Семафор блокирующий примитив
Маньяк Робокряк колесит по городу
Re[3]: Временный блокировщик
От: vopl Россия  
Дата: 04.02.24 07:32
Оценка:
Здравствуйте, Marty, Вы писали:

M>Здравствуйте, vopl, Вы писали:


M>>>Ну или как лучше сделать? Может, есть что-то стандартное, чем изобретать велосипеды?


V>>У тебя получился Семафор



M>Семафор блокирующий примитив

У тебя он тоже блокирующий, только блокирует не поток а семантику. Это всего лишь вопрос точки зрения. Но, хозяин барин, пусть это не Семафор
Re[2]: Временный блокировщик
От: reversecode google
Дата: 04.02.24 15:54
Оценка:
шаред мютекс проседает на любых тестах по сравнении с обычным мютексом

даже доклад на какой то конфе было
где чел там пытался переизобретать что то даже на атомиках что бы ускориться
Re: Временный блокировщик
От: reversecode google
Дата: 04.02.24 16:37
Оценка:
std::recursive_mutex не оно?
Re[4]: Временный блокировщик
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 04.02.24 18:59
Оценка:
Здравствуйте, vopl, Вы писали:

M>>Семафор блокирующий примитив

V>У тебя он тоже блокирующий, только блокирует не поток а семантику. Это всего лишь вопрос точки зрения. Но, хозяин барин, пусть это не Семафор

Да пусть и семафор

Окай, семафор, где у нас есть проверяющий неблокирующий семафор?
Маньяк Робокряк колесит по городу
Re[2]: Временный блокировщик
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 04.02.24 19:06
Оценка:
Здравствуйте, reversecode, Вы писали:

R>std::recursive_mutex не оно?


Он же рекурсивен только для захватившего потока, для остальных блокирует, не?
Маньяк Робокряк колесит по городу
Re[5]: Временный блокировщик
От: reversecode google
Дата: 04.02.24 19:06
Оценка: +1
у нас есть, у тебя хз
https://en.cppreference.com/w/cpp/header/semaphore
Re: Временный блокировщик
От: tryAnother  
Дата: 05.02.24 08:13
Оценка:
Чтобы не потерять разблокировку, удобнее использовать raii, а не руками вызывать Lock (если код конечно позволяет)
тогда счетчик можно перенести в класс Locable.


class Locker;

class Locable
{
    friend Locker;
    std::atomic<int> m_counter;
  
public:
    Locable(): m_counter(0) {}
    operator bool () const {return !m_counter; }
};

class Locker
{
    Locker(const Locker&) = delete;
    Locker& operator=(const Locker&) = delete;
    
    Locable & m_locable;
public:
    Locker(Locable & l):m_locable(l) { ++m_locable.m_counter; }
    ~Locker() {--m_locable.m_counter;}
};
Отредактировано 05.02.2024 14:07 tryAnother . Предыдущая версия .
Re[2]: Временный блокировщик
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 05.02.24 09:10
Оценка:
Здравствуйте, tryAnother, Вы писали:

A>Чтобы не потерять разблокировку, удобнее использовать raii, а не руками вызывать Lock (если код конечно позволяет)


Это высшая магия, естественно, я её буду использовать. Когда будет надо. Например, в скопах
Маньяк Робокряк колесит по городу
Re: Временный блокировщик
От: Chorkov Россия  
Дата: 05.02.24 13:50
Оценка:
Здравствуйте, Marty, Вы писали:

M>Здравствуйте!



M>Где-то в каком-то потоке периодически что-то производится, какие-то действия. Иногда надо временно запретить их производить.


M>В других потоках, или в том же потоке, можно запрещать, рекурсивно, главное, разлочить столько же раз, сколько и залочил.


M>Что-то городить с какими-то примитивами синхронизации не вижу смысла, ну, может я ошибаюсь.

...

M>Ну или как лучше сделать? Может, есть что-то стандартное, чем изобретать велосипеды?


shared_mutex:

class Locable
{
   mutable std::shared_mutex  m_mutex;

public:
   void lock() { m_mutex.lock_shared(); }
   void unlock() { m_mutex.unlock_shared(); }
   bool isLocked() const {
        if( ! m_mutex.try_lock() ) 
             return true;
        m_mutex.unlock();
        return true;
   }
};
Отредактировано 05.02.2024 13:54 Chorkov . Предыдущая версия .
Re[2]: Временный блокировщик
От: reversecode google
Дата: 05.02.24 13:59
Оценка:
https://rsdn.org/forum/cpp.applied/8683879.1
Автор: reversecode
Дата: 04.02.24
Re[2]: Временный блокировщик
От: Кодт Россия  
Дата: 06.02.24 12:51
Оценка:
Здравствуйте, vopl, Вы писали:

V>У тебя получился Семафор


Не получился, потому что у семафора семантика "поднял где угодно кто угодно" / "опустил и ждёшь".
А тут — один поднял-опустил без блокировки, другой пытается пролезть и ждёт.
Перекуём баги на фичи!
Re[3]: Временный блокировщик
От: vopl Россия  
Дата: 06.02.24 12:58
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Здравствуйте, vopl, Вы писали:


V>>У тебя получился Семафор


К>Не получился, потому что у семафора семантика "поднял где угодно кто угодно" / "опустил и ждёшь".

К>А тут — один поднял-опустил без блокировки, другой пытается пролезть и ждёт.

Ну, это если смотреть со стороны его реализации в конкретных схемах вытесняющего многопотока. Чуть абстрактнее если подняться, то семафор это "... счётчик, над которым можно производить две атомарные операции: увеличение и уменьшение значения на единицу, при этом операция уменьшения для нулевого значения счётчика является блокирующейся...". Вот по такой семантике у него вполне семафор, ноль как граница блокируемости, выше ноля свободно, ноль и ниже — заблокировано (или наоборот, не важно). Хотя, это все вопрос трактовки, спорить не стану, просто поясняю свой ход мыслей.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.