Асинхронные вызовы
От: sraider http://dvinogradov.blogspot.com
Дата: 18.06.14 11:51
Оценка:
Существуют ли библиотеки для удобного программирования асинхронных вызовов?

Поясню задачу.
Допустим, есть GUI, где пользователь запускает задачу. Задача может выглядеть так:

some_quick_code1;
Load("http://url"); // has async interface too, can be used asynchronously
some_quick_code2;
ReadFromDataBase("select * from db"); // has async interface too, can be used asynchronously
some_quick_code3;
ComputeLargeData(); // has async interface too, can be used asynchronously
some_quick_code4;
WriteToDisk("out.txt"); // has async interface too, can be used asynchronously
some_quick_code5;


Пока все это выполняется, пользователь:
а) Может нажать "Отмена". Приложение все еще выполняется, но задачу уже можно прекращать.
б) Может вообще закрыть приложение. Работу приложения нужно завершить.

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

Соответственно вопрос, как оформить приведенный выше код в асинхронном стиле?
Re: Кооперативная отмена
От: Qbit86 Кипр
Дата: 18.06.14 12:20
Оценка:
Здравствуйте, sraider, Вы писали:

S>Существуют ли библиотеки для удобного программирования асинхронных вызовов?


S>а) Может нажать "Отмена". Приложение все еще выполняется, но задачу уже можно прекращать.

S>б) Может вообще закрыть приложение. Работу приложения нужно завершить.

S>То есть выполнение всей задачи нужно уметь прерывать.

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

Для этого используется механизм кооперативной отмены. То есть работа прерывается не в одностороннем порядке вызывающей стороной; вызываемая сторона должна «согласиться» прерваться. Посмотри в MSDN реализацию и примеры использования .NET-классов CancellationToken и CancellationTokenSource, и сделай по аналогии в C++. Но для этого асинхронный API должен поддерживать вызовы с передачей токена отмены, и его опрос.
Глаза у меня добрые, но рубашка — смирительная!
Re[2]: Кооперативная отмена
От: Abyx Россия  
Дата: 18.06.14 12:37
Оценка:
Здравствуйте, Qbit86, Вы писали:

S>>а) Может нажать "Отмена". Приложение все еще выполняется, но задачу уже можно прекращать.

S>>б) Может вообще закрыть приложение. Работу приложения нужно завершить.

S>>То есть выполнение всей задачи нужно уметь прерывать.

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

Q>Для этого используется механизм кооперативной отмены. То есть работа прерывается не в одностороннем порядке вызывающей стороной; вызываемая сторона должна «согласиться» прерваться. Посмотри в MSDN реализацию и примеры использования .NET-классов CancellationToken и CancellationTokenSource, и сделай по аналогии в C++. Но для этого асинхронный API должен поддерживать вызовы с передачей токена отмены, и его опрос.


все можно сделать проще,
работа уходит чего-то ждать, и если она была отменена — ей бросается исключение.

собственно работы с таймаутом делаются так же.

вместо исключения может быть код ошибки, но это так надежно, т.к. ее можно проигнорировать.
In Zen We Trust
Re[3]: Кооперативная отмена
От: Qbit86 Кипр
Дата: 18.06.14 12:40
Оценка:
Здравствуйте, Abyx, Вы писали:

A>работа уходит чего-то ждать, и если она была отменена — ей бросается исключение.


Напиши пример, как «работе» бросить исключение.
Глаза у меня добрые, но рубашка — смирительная!
Re[4]: Кооперативная отмена
От: Abyx Россия  
Дата: 18.06.14 13:23
Оценка:
Здравствуйте, Qbit86, Вы писали:

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


A>>работа уходит чего-то ждать, и если она была отменена — ей бросается исключение.


Q>Напиши пример, как «работе» бросить исключение.


тривиальный пример — это boost::thread::interrupt
In Zen We Trust
Re[5]: Кооперативная отмена
От: Qbit86 Кипр
Дата: 18.06.14 13:31
Оценка:
Здравствуйте, Abyx, Вы писали:

A>>>работа уходит чего-то ждать, и если она была отменена — ей бросается исключение.

Q>>Напиши пример, как «работе» бросить исключение.
A>тривиальный пример — это boost::thread::interrupt

Никогда не использовал, посмотрел сейчас по диагонали доку — там тоже кооперативная отмена: есть interruption points, в которых вызывающая сторона проверяет, не была ли запрошена отмена. Если была, то прибивает себя исключением. Частная харкодная раелизация общей идеи (опрос «boost::this_thread::interruption_requested()» вместо «token.CancellationRequested»).
Глаза у меня добрые, но рубашка — смирительная!
Re: Асинхронные вызовы
От: smeeld  
Дата: 18.06.14 13:31
Оценка:
Здравствуйте, sraider, Вы писали:

S>Существуют ли библиотеки для удобного программирования асинхронных вызовов?


Общей, для работы и с файлами, и с сетью, и вообще с чем угодно, вроде сеансов с СУБД
на её клиентской либе, наверно, все-таки нет.
Но таковую можно расписать самому. Ключевыми элементами будт потоки, очередя.
Для каждого типа задачи свой поток, использующий асинхронные фреймворки конкретного типа
задачи, для файлов свои( в POSIX libaio), для сети свои (epoll/boost::asio). И поток управленец,который ставит задачи
в очередя, и отменяет их, высылая сигналы с номером задачи, потокам исполнителям(в POSIX, pthread_sigqueue/pthread_kill ).
Re: Асинхронные вызовы
От: BulatZiganshin  
Дата: 20.06.14 21:22
Оценка:
Здравствуйте, sraider, Вы писали:

S>Существуют ли библиотеки для удобного программирования асинхронных вызовов?


http://stackoverflow.com/questions/11423426/how-does-libuv-compare-to-boost-asio?answertab=votes#tab-top

S>Соответственно вопрос, как оформить приведенный выше код в асинхронном стиле?


через лямбды как в node.js в принципе можно. для большего удобства рантайм должен сам создавать synchronization points между операторами, что в C++ невохможно
Люди, я люблю вас! Будьте бдительны!!!
Re: Асинхронные вызовы
От: c-smile Канада http://terrainformatica.com
Дата: 21.06.14 01:30
Оценка:
Здравствуйте, sraider, Вы писали:

В качестве идеи как это можно сделать в C++11:

// worker thread function
void ReadFromDataBase(const char* rq, UIObject* some) {

  db::recordset rs = db.select(rq); 
  uint rec_no = 0;
  for( db::cursor crs = rs.first(); crs.valid(); crs.advance(); ) 
  {
    ++rec_no;  // in worker thread 
    GUI_CODE_START
      // this runs in GUI thread  
      some->showRecordNo(rec_no, crs);
    GUI_CODE_END
  }
}


GUI_CODE_START / GUI_CODE_END это маркеры кода который исполняется в GUI потоке блокируя данный worker thread пока GUI его не исполнит.

GUI_CODE_START / GUI_CODE_END описаны как:

#define GUI_CODE_START gui_exec([&]() {
  
#define GUI_CODE_END });


Плюс код и статьи выше.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.