В STL почему нет аналога Event Objects(Win32)
От: PowerUserX  
Дата: 25.02.15 12:58
Оценка: +2
Вопрос к спецам.
Почему В STL почему нет аналога Event Objects(Win32)?

Пример применения .... что то типа

1 поток . просыпаемся после периода
while (1)
{
bool isBreak = pThis->syncObject.wait(waitSecondTime * 1000); == WAIT_OBJECT_0 == WaitForSingleObject(h, dwMilliseconds);
if (isBreak || pThis->needStopped == 1)
return 1;
.....
}

2 поток . Надо закончить обработчик в GUI по "закрыть"
....
syncObject.set();
Re: В STL почему нет аналога Event Objects(Win32)
От: niXman Ниоткуда https://github.com/niXman
Дата: 25.02.15 13:00
Оценка: :)
какое отношение STL имеет к Win32?
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re[2]: В STL почему нет аналога Event Objects(Win32)
От: PowerUserX  
Дата: 25.02.15 13:05
Оценка:
Здравствуйте, niXman, Вы писали:

X>какое отношение STL имеет к Win32?


Это то понятно
Но паттерн как event(c реализзацией wait/wait_for) применятся широко.
Почему в STL не реализовали его ... только cond_var
Re[3]: В STL почему нет аналога Event Objects(Win32)
От: dead0k  
Дата: 25.02.15 14:00
Оценка:
Здравствуйте, PowerUserX, Вы писали:
PUX> только cond_var

У которого есть wait_for/wait_until.
Чего не хватает?
Re: В STL почему нет аналога Event Objects(Win32)
От: uzhas Ниоткуда  
Дата: 25.02.15 14:07
Оценка: 4 (1)
Здравствуйте, PowerUserX, Вы писали:

PUX>Вопрос к спецам.

PUX>Почему В STL почему нет аналога Event Objects(Win32)?

Event идеологически многим не нравится
в качестве альтернативы предлагают использовать condition_variable + mutex

ссылки по теме:
http://stackoverflow.com/questions/5233681/windows-condition-variable-vs-event
http://stackoverflow.com/questions/1215402/difference-between-event-object-and-condition-variable
Отредактировано 25.02.2015 16:48 uzhas . Предыдущая версия .
Re[4]: В STL почему нет аналога Event Objects(Win32)
От: PowerUserX  
Дата: 25.02.15 14:24
Оценка:
Здравствуйте, dead0k, Вы писали:

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

PUX>> только cond_var

D>У которого есть wait_for/wait_until.

D>Чего не хватает?


Быстро написал
имел ввиду что есть mutex b cond_var

а хотел бы event c методами типа wait b wait_time_for
Re[2]: В STL почему нет аналога Event Objects(Win32)
От: jahr  
Дата: 25.02.15 14:25
Оценка:
Здравствуйте, uzhas, Вы писали:

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


PUX>>Вопрос к спецам.

PUX>>Почему В STL почему нет аналога Event Objects(Win32)?

U>Event идеологически многим не нравится

U>в качестве альтернативы предлагают использовать conditional_variable + mutex

U>ссылки по теме:

U>http://stackoverflow.com/questions/5233681/windows-condition-variable-vs-event
U>http://stackoverflow.com/questions/1215402/difference-between-event-object-and-condition-variable

Спасибо за ссылки, стало понятнее, как на condition_variable эмулировать event.)

Но все равно осталось непонятным, почему кроссплатформенные библиотеки не реализуют такой удобный примитив синхронизации, как event: первая Ваша ссылка очень наглядно демонстрирует, насколько код с event проще и понятнее.) В чем именно состоят идеологические дефекты event'а? Подозреваю, что stl, QT и другие кроссплатформенные библиотеки не используют аналога виндового события потому, что на юниксе его сложно реализовать.)
Re: В STL почему нет аналога Event Objects(Win32)
От: Pavel Dvorkin Россия  
Дата: 25.02.15 14:34
Оценка: 17 (2) +3 -1
Здравствуйте, PowerUserX, Вы писали:

PUX>Почему В STL почему нет аналога Event Objects(Win32)?


ИМХО потому что нет реализации в ядре систем, на которые пришлось все же ориентироваться.

Contrary to popular belief, event objects – a construct particular to MS Windows and not found in *NIX OS:es – are useful in many instances where exact thread execution control is needed. For instance, you may want to have a thread pausing itself while starting another one.
However, if you post a question on a *NIX forum about how to implement event objects or something similar, you will likely get an answer along the lines of “just use mutexes”. Unfortunately, there is no “just” about it. Implementing event objects is a bit tricky, as there are several instances where race conditions or deadlocks can occur.

http://win32eoposix.sourceforge.net/

Кстати, в ядре Windows есть еще специальный объект EventPair, для которого можно атомарно дождаться одного ивента пары и установить другой ивент, но в Win API он не экспонируется, только через ntdll.dll
With best regards
Pavel Dvorkin
Отредактировано 25.02.2015 14:39 Pavel Dvorkin . Предыдущая версия .
Re[3]: В STL почему нет аналога Event Objects(Win32)
От: uzhas Ниоткуда  
Дата: 25.02.15 16:37
Оценка:
Здравствуйте, jahr, Вы писали:

J>В чем именно состоят идеологические дефекты event'а? Подозреваю, что stl, QT и другие кроссплатформенные библиотеки не используют аналога виндового события потому, что на юниксе его сложно реализовать.)


я бы предположил, что связка cond_var + mutex более мощная, нежели Event. последний может быть реализован с помощью первых двух
так что с реализацией на линуксе проблем не будет

вот интересный поток сознания на тему как сделать posix cond_var на win : http://www.cs.wustl.edu/~schmidt/win32-cv-1.html
Re[2]: В STL почему нет аналога Event Objects(Win32)
От: uzhas Ниоткуда  
Дата: 25.02.15 16:47
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Implementing event objects is a bit tricky, as there are several instances where race conditions or deadlocks can occur.

PD>http://win32eoposix.sourceforge.net/

тут основная сложность в реализации WaitForMultipleObjects, которая далеко не всегда нужна. без нее все должно быть просто (по прикидкам)
Re: В STL почему нет аналога Event Objects(Win32)
От: B0FEE664  
Дата: 25.02.15 16:54
Оценка: +1
Здравствуйте, PowerUserX, Вы писали:

PUX>Вопрос к спецам.

PUX>Почему В STL почему нет аналога Event Objects(Win32)?

Сколько я не задавал этот вопрос, мне разумного ответа никто не дал. Поэтому приходится делать так:

#include <assert.h>
#include <chrono>
#include <condition_variable>
#include <iostream>
#include <memory>
#include <mutex>
#include <thread>


class Event
{
  public:
    Event() : m_bEvent(false) {}
   ~Event(){}
  public:
    // return true  if the event occured
    // return false if the timeout elapsed
    template<typename DurationType>
    bool TimedWait(DurationType const& rTimeout)
    {
        bool bTimeout = false;
        bool bRet;
        std::unique_lock< std::mutex > oNotifierLock( m_oMutex );
    
        while( !m_bEvent && !bTimeout )
        {
            bTimeout = std::cv_status::timeout == m_oConditionVariable.wait_for(oNotifierLock, rTimeout);
        }
        bRet = m_bEvent;
        m_bEvent = false;
        return bRet;
    }

    void NotifyOne()
    {
        {
            std::unique_lock< std::mutex > oNotifierLock(m_oMutex);
            m_bEvent = true;
        }
        m_oConditionVariable.notify_one();
    }
  private:
    std::mutex              m_oMutex;
    std::condition_variable m_oConditionVariable;
    bool                    m_bEvent;
};


void PingThread(std::shared_ptr<Event> pPingEvent, std::shared_ptr<Event> pPongEvent)
{
    assert(NULL != pPingEvent);
    assert(NULL != pPongEvent);

    const std::chrono::seconds oTimeout(1);

    for(int i = 0; i < 100; i++)
    {
        std::cout << i << " Ping...";
        pPingEvent->NotifyOne();
        if ( !pPongEvent->TimedWait(oTimeout) )
        {
            std::cout << "\npong is lost\n";
        }
    }
}


void PongThread(std::shared_ptr<Event> pPingEvent, std::shared_ptr<Event> pPongEvent)
{
    assert(NULL != pPingEvent);
    assert(NULL != pPongEvent);

    const std::chrono::seconds oTimeout(1);

    while( pPingEvent->TimedWait(oTimeout) )
    {
        std::cout << "pong\n";
        pPongEvent->NotifyOne();
    }
    std::cout << "No more ping? Did I won?\n";
}


int main(int argc, char* argv[])
{
  std::shared_ptr<Event> pPingEvent = std::make_shared<Event>();
  std::shared_ptr<Event> pPongEvent = std::make_shared<Event>();

  std::cout << "Start...\n";

  std::thread oPingThread(PingThread, pPingEvent, pPongEvent);
  std::thread oPongThread(PongThread, pPingEvent, pPongEvent);

  oPingThread.join();
  oPongThread.join();

  std::cout << "The end.\n";

  return 0;
}
И каждый день — без права на ошибку...
Re: В STL почему нет аналога Event Objects(Win32)
От: Шахтер Интернет  
Дата: 25.02.15 17:18
Оценка: -1
Здравствуйте, PowerUserX, Вы писали:

PUX>Вопрос к спецам.

PUX>Почему В STL почему нет аналога Event Objects(Win32)?

Недотымкали. Теоретики, что с них взять. Это далеко не единственный косяк STL.
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re[2]: В STL почему нет аналога Event Objects(Win32)
От: Шахтер Интернет  
Дата: 25.02.15 17:20
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

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


PUX>>Почему В STL почему нет аналога Event Objects(Win32)?


PD>ИМХО потому что нет реализации в ядре систем, на которые пришлось все же ориентироваться.


CCore замечательно работает и поверх Windows, и поверх Linux.
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Re: В STL почему нет аналога Event Objects(Win32)
От: BulatZiganshin  
Дата: 26.02.15 01:25
Оценка: :)
Здравствуйте, PowerUserX, Вы писали:

PUX>Почему В STL почему нет аналога Event Objects(Win32)?


объекты синхронизации в C++ сделаны по образцу posix api. так что правильный подход — осваивать condition variables и писать алгоритмы под них
Люди, я люблю вас! Будьте бдительны!!!
Re: В STL почему нет аналога Event Objects(Win32)
От: c-smile Канада http://terrainformatica.com
Дата: 26.02.15 05:49
Оценка:
Здравствуйте, PowerUserX, Вы писали:

Наверное потому что такой примитив добавить тривиально можно, как-то так:

    class event
    {
      event( const event& ) = delete;
      event& operator=(const event&) = delete;

      std::condition_variable_any _var;
      std::mutex                  _mtx;
    public:
      event() {}
      void signal() {
          _var.notify_one();
      }
      void wait() {
          std::unique_lock<std::mutex> lock(_mtx);
          _var.wait(lock);
      }

    };



wait(chrono::duration) добавить по вкусу.
Re[3]: В STL почему нет аналога Event Objects(Win32)
От: Pavel Dvorkin Россия  
Дата: 26.02.15 07:11
Оценка:
Здравствуйте, Шахтер, Вы писали:

Ш>CCore замечательно работает и поверх Windows, и поверх Linux.


Ну и что ? Посмотри ссылку, которую я привел, там как раз моделирование ивентов с помощью мютексов. Я же не говорю, что сделать нельзя. Я просто думаю, что в виду того, что ивенты ядром линукса не поддерживаются, авторы STL решили их не включать. Моделируйте сами как хотите.
With best regards
Pavel Dvorkin
Re[2]: В STL почему нет аналога Event Objects(Win32)
От: PowerUserX  
Дата: 26.02.15 08:13
Оценка:
Здравствуйте, c-smile, Вы писали:

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


CS>Наверное потому что такой примитив добавить тривиально можно, как-то так:


CS>
CS>    class event
CS>    {
CS>      event( const event& ) = delete;
CS>      event& operator=(const event&) = delete;

CS>      std::condition_variable_any _var;
CS>      std::mutex                  _mtx;
CS>    public:
CS>      event() {}
CS>      void signal() {
CS>          _var.notify_one();
CS>      }
CS>      void wait() {
CS>          std::unique_lock<std::mutex> lock(_mtx);
CS>          _var.wait(lock);
CS>      }

CS>    };
CS>



CS>wait(chrono::duration) добавить по вкусу.


А ложные сробатывания + bool переменная -> кода поболей
Хотя ... может и правильно
Re[2]: В STL почему нет аналога Event Objects(Win32)
От: uzhas Ниоткуда  
Дата: 26.02.15 09:20
Оценка:
Здравствуйте, c-smile, Вы писали:

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


CS>Наверное потому что такой примитив добавить тривиально можно

можно

CS>как-то так

ну далековато от истины. лучше см. код B0FEE664
Re[2]: В STL почему нет аналога Event Objects(Win32)
От: Videoman Россия https://hts.tv/
Дата: 26.02.15 10:27
Оценка:
Здравствуйте, c-smile, Вы писали:

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


CS>Наверное потому что такой примитив добавить тривиально можно, как-то так:


CS>
CS>    class event
CS>    {
CS>      event( const event& ) = delete;
CS>      event& operator=(const event&) = delete;

CS>      std::condition_variable_any _var;
CS>      std::mutex                  _mtx;
CS>    public:
CS>      event() {}
CS>      void signal() {
CS>          _var.notify_one();
CS>      }
CS>      void wait() {
CS>          std::unique_lock<std::mutex> lock(_mtx);
CS>          _var.wait(lock);
CS>      }

CS>    };
CS>



CS>wait(chrono::duration) добавить по вкусу.


Абсолюьно неправильная реализация :
Во-первых, wait может сработать просто так (фантомные просыпания).
Во-вторых, если один поток сделает notify_one а второй не будет сидеть в этот момент на wait, то событие уйдет в небытие. О нем никто никогда не узнает.
Отредактировано 26.02.2015 11:55 Videoman . Предыдущая версия .
Re[4]: В STL почему нет аналога Event Objects(Win32)
От: Шахтер Интернет  
Дата: 26.02.15 18:43
Оценка:
Здравствуйте, Pavel Dvorkin, Вы писали:

PD>Здравствуйте, Шахтер, Вы писали:


Ш>>CCore замечательно работает и поверх Windows, и поверх Linux.


PD>Ну и что ? Посмотри ссылку, которую я привел, там как раз моделирование ивентов с помощью мютексов. Я же не говорю, что сделать нельзя. Я просто думаю, что в виду того, что ивенты ядром линукса не поддерживаются, авторы STL решили их не включать. Моделируйте сами как хотите.


Это называется упражнение в телепатии.
Как причина -- идиотская. В ядрах и не должно быть реализации всех мыслимых типов синхронизирующих объектов. Должен быть достаточный базис, позволяющий реализовывать их в приложениях.

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

Например, библиотека fstream скрывает детали низкоуровневой работы с файлами. В Windows мы вызываем функции ReadFile/WriteFile для чтения/записи в файл, а в Linux read/write.
Используя стандартную библиотеку, можно абстрагироваться от этого и писать переносимый код.
В XXI век с CCore.
Копай Нео, копай -- летать научишься. © Matrix. Парадоксы
Отредактировано 26.02.2015 18:54 Шахтер . Предыдущая версия .
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.