powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Кроссплатформенный WaitForSingleObject
18 сообщений из 18, страница 1 из 1
Кроссплатформенный WaitForSingleObject
    #39692019
Ciplusor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть что то подобное? У меня есть объект, который позволяет потокозащищенно записывать в очередь буфер данных, который потом забирает обрабатывающий поток. В общем виде выглядит так:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
    // Обработка очереди буферов
    class TBufferTransport
    {
    private:
        // Мьютекс для потокозащищенной работы 
        std::mutex * FMutex = nullptr;
        // Очередь буферов
        std::queue<TBuffer*> * FQueue = nullptr;
    public:
        // Добавить буфер
        void Push(TBuffer * ABuffer)
        // Забрать буфер 
        TBuffer * Pop();
    };



И крутится должно это все в разных потоках подтипа (инстанс опущен для краткости)

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
    void TAuth::Execute(TAuth * AInstance)
    {
        while (bool TmpAccept = AInstance->FQueue->WaitForBuffer())
        {
            if (TmpAccept)
                AInstance->Work(AInstance->FQueue->Pop());
            else
               break;
        }
    }



Зависая на методе FQueue->WaitForBuffer() до тех пор, пока не появится знак что в очереди появился новый объект и его можно обработать.

В Windows я бы воспользовался WaitForSingleObject + Event, а вот в кросс что-то погуглил - ничего путевого не нашел, а колхозными слипами как то очень не хочется.
...
Рейтинг: 0 / 0
Кроссплатформенный WaitForSingleObject
    #39692024
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В линуксе нет event, но есть condition variable, но это немного другое. Оно теперь есть в виндовсе. Я пытался прийти к общему знаменателю, итого тут 18712566
...
Рейтинг: 0 / 0
Кроссплатформенный WaitForSingleObject
    #39692026
Ciplusor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T, >> тем более что для condition_variable изначально в документации заявлена возможность ложного срабатывания

Что-то как-то хз =D тогда уж слипами надежнее. Но должно же быть какое то базовое решение, неужели все на слипах живут
...
Рейтинг: 0 / 0
Кроссплатформенный WaitForSingleObject
    #39692030
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CiplusorЧто-то как-то хз =D тогда уж слипами надежнее.

А в чём проблема-то с ложным срабатыванием? Для очереди оно сугубо пофиг: всё равно ты в
цикле проверяешь голову очереди и если она пустая - ждёшь сигнала.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Кроссплатформенный WaitForSingleObject
    #39692032
Ciplusor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry SibiryakovCiplusorЧто-то как-то хз =D тогда уж слипами надежнее.

А в чём проблема-то с ложным срабатыванием? Для очереди оно сугубо пофиг: всё равно ты в
цикле проверяешь голову очереди и если она пустая - ждёшь сигнала.
Тогда заводить дополнительную переменную которая будет отвечать за учет прерывания цикла ожидания. Но вообще мне страшно пользоваться тем, что внезапно может работать со сбоями. Особенно если на далеком сервере все посыпется с хрен пойми каким стеком 8(
...
Рейтинг: 0 / 0
Кроссплатформенный WaitForSingleObject
    #39692033
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот так выглядит pop у моей очереди:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
Request* Queue::pop(unsigned timeout)
{
     do
     { // Scope
         CriticalSectionGuard lock(guard);
         Request* Result = head;
         if (Result != nullptr)
         {
             head = Result->next;
             if (tail == Result || head == nullptr) // Duplicate condition for bugs tolerancy
             {
                 tail = nullptr;
             }
             return Result;
         }
     }
     while (wait(timeout));
     return nullptr;
}


Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Кроссплатформенный WaitForSingleObject
    #39692035
Ciplusor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
За condition variable спасибо, на хабре нашел разъясняющую статью, попробую прикрутить
...
Рейтинг: 0 / 0
Кроссплатформенный WaitForSingleObject
    #39692036
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CiplusorТогда заводить дополнительную переменную которая будет отвечать за учет
прерывания цикла ожидания.

У тебя уже есть такая переменная: это голова очереди. Цикл автоматически прерывается если
из очереди есть что выбрать.

CiplusorНо вообще мне страшно пользоваться тем, что внезапно может работать со сбоями.

false positive это гораздо лучше, чем false negative. Проблема была бы если вы ожидание
иногда не прерывалось при взведении флага.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Кроссплатформенный WaitForSingleObject
    #39692038
Ciplusor
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry SibiryakovУ тебя уже есть такая переменная: это голова очереди. Цикл автоматически прерывается если
из очереди есть что выбрать.Не, я имел ввиду переменную - аналог вашего (wait(timeout)); которая прервет цикл, если поток его выполняющий нужно будет остановить
...
Рейтинг: 0 / 0
Кроссплатформенный WaitForSingleObject
    #39692043
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CiplusorНе, я имел ввиду переменную - аналог вашего (wait(timeout)); которая прервет цикл, если
поток его выполняющий нужно будет остановить

А, так тебе не только очередь надо ждать? Тогда это уже WaitForMultipleObjects и тут с
кроссплатформенностью совсем туго.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Кроссплатформенный WaitForSingleObject
    #39692142
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry SibiryakovПроблема была бы если вы ожидание иногда не прерывалось при взведении флага.

Как понимаю такая проблема тоже есть. Например поток обработки закончил обрабатывать очередь, почти дошел до засыпания на cv.wait(), в этот момент другой поток вызывает cv.notify_one() и этот вызов игнорируется, т.к. первый не успел заснуть на cv.wait().
...
Рейтинг: 0 / 0
Кроссплатформенный WaitForSingleObject
    #39692152
Фотография OoCc
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TDimitry SibiryakovПроблема была бы если вы ожидание иногда не прерывалось при взведении флага.

Как понимаю такая проблема тоже есть. Например поток обработки закончил обрабатывать очередь, почти дошел до засыпания на cv.wait(), в этот момент другой поток вызывает cv.notify_one() и этот вызов игнорируется, т.к. первый не успел заснуть на cv.wait().

Dima T, такой проблемы нет. Как минимум в g++
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
class condition_variable
{

.......................

     void
     notify_one() noexcept
     {
       lock_guard<mutex> __lock(*_M_mutex);
       _M_cond.notify_one();
     }
 
     void
     notify_all() noexcept
     {
       lock_guard<mutex> __lock(*_M_mutex);
       _M_cond.notify_all();
     }
 
     template<typename _Lock>
       void
       wait(_Lock& __lock)
       {
         shared_ptr<mutex> __mutex = _M_mutex;
         unique_lock<mutex> __my_lock(*__mutex);
         _Unlock<_Lock> __unlock(__lock);
         // *__mutex must be unlocked before re-locking __lock so move
         // ownership of *__mutex lock to an object with shorter lifetime.
         unique_lock<mutex> __my_lock2(std::move(__my_lock));
         _M_cond.wait(__my_lock2);
       }
 



Лишнее срабатыванее ждущего рабочего потока может случится при вызове notify_all() и очередь короче количества рабочих потоков, или вообще пуста. Это стандартная ситуация.
...
Рейтинг: 0 / 0
Кроссплатформенный WaitForSingleObject
    #39692177
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Допустим оба потока выполнялись одним ядром проца и контекст переключился сразу после опустошения очереди.
Схематично так
Поток 1Поток 2for(;;) { while(!queue.empty()) { ... обработка очереди } queue.push(...); cv.notify_one(); cv.wait();}

Как я понимаю тут wait() уйдет в ожидание, хотя очередь уже не пуста.
...
Рейтинг: 0 / 0
Кроссплатформенный WaitForSingleObject
    #39692195
Фотография OoCc
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TДопустим оба потока выполнялись одним ядром проца и контекст переключился сразу после опустошения очереди.
Схематично так
Поток 1Поток 2for(;;) { while(!queue.empty()) { ... обработка очереди } queue.push(...); cv.notify_one(); cv.wait();}

Как я понимаю тут wait() уйдет в ожидание, хотя очередь уже не пуста.
К собственно condition_variable это не относится. Это проблема конкретного кода.
...
Рейтинг: 0 / 0
Кроссплатформенный WaitForSingleObject
    #39692207
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
OoCcК собственно condition_variable это не относится. Это проблема конкретного кода.
Код типовой. Для виндового EVENT данной проблемы нет.

Хотя тут тоже можно эту ситуацию исключить дополнительной проверкой после блокировки мутекса
Код: plaintext
1.
2.
std::unique_lock<std::mutex> lck(mtx);
if(queue.empty()) cv.wait(lck);
...
Рейтинг: 0 / 0
Кроссплатформенный WaitForSingleObject
    #39692217
Фотография OoCc
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TOoCcК собственно condition_variable это не относится. Это проблема конкретного кода.
Код типовой. Для виндового EVENT данной проблемы нет.

Хотя тут тоже можно эту ситуацию исключить дополнительной проверкой после блокировки мутекса
Код: plaintext
1.
2.
std::unique_lock<std::mutex> lck(mtx);
if(queue.empty()) cv.wait(lck);


типовой код - делается класс очередь multiple producers / multiple consumers. А уж на основе чего она сделана не имеет значения. И с condition_variable нам нет никаких проблем.
...
Рейтинг: 0 / 0
Кроссплатформенный WaitForSingleObject
    #39692260
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima TКак я понимаю тут wait() уйдет в ожидание, хотя очередь уже не пуста.

Потому что не так они должны использоваться. Они всегда работают в паре с мутексом.

Семафоры могут быть удобнее для организации очереди, но они не входят в стандарт С++.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Кроссплатформенный WaitForSingleObject
    #39692303
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ciplusor,

в древности этот примитив назывался chanel, был у меня где-то исходник, найти не могу

помню, что для реализации использовалось 3 критические секции
...
Рейтинг: 0 / 0
18 сообщений из 18, страница 1 из 1
Форумы / C++ [игнор отключен] [закрыт для гостей] / Кроссплатформенный WaitForSingleObject
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]