[c++] futures
От: alexeiz  
Дата: 06.03.06 09:40
Оценка: 21 (5)
Небольшая библиотечка, предоставляющая возможность асинхронного выполнения задач.

Навеяно идеями Kevlin Henney (http://www.two-sdg.demon.co.uk/curbralan/papers/accu/MoreC++Threading.pdf, http://www.two-sdg.demon.co.uk/curbralan/papers.html).

В boost sandbox'е есть уже что-то подобное (я тут немного припоздал ). Но у них жесткая привязка к boost::thread, тогда как у меня это можно конфигурировать с помощью executor'ов. Пока что реализовано три вида executor'ов: instant_executor — сразу выполняет задачу в текущем потоке, thread_executor — в отдельном потоке, созданном с помощью boost::thread, atl_thread_pool_executor — в ATL пуле.

Реализована поддержка исключений (так же нет в boost'овском варианте). Исключение, выбрасываемое в отдельном потоке, перебрасывается в текущем потоке при попытке узнать результат исполнения задачи.

Естественно, это всё работает с лямбдами и boost::function за милую душу.

Платформа: Win32.
Зависимости: boost, ATL

Файл здесь: http://rsdn.ru/File/15955/futures_redist.zip

Пример:
int foo() { // some function }
void bar() {}
void throwing_bar() { // throw my_exception derived from rethrowable_error }

thread_executor exec;
future<int> foo_joiner = exec(foo);  // queue execution
int result = foo_joiner();  // get the result

atl_thread_pool_executor atlexec(2);  // number of threads = 2
future<> bar_joiner = altexec(bar);

if (bar_joiner)   // finished yet?
{
}

bar_joiner();  // wait for completion

try
{
    future<> throwing_joiner = altexec(throwing_bar);  // execute thrower in a separate thread
    throwing_joiner();  // exception is rethrown here!
}
catch (my_exception &)
{
   // the exception has the correct type
}
Re: [c++] futures
От: 0xDEADBEEF Ниоткуда  
Дата: 07.03.06 14:33
Оценка:
Здравствуйте, alexeiz, Вы писали:

A>Небольшая библиотечка, предоставляющая возможность асинхронного выполнения задач.


Достаточно неплохо. Но хотелось бы:

— Независимости. То есть, чтобы эта штука работала на любом пуле потоков. Причем, свойства пула должны быть (а)достаточно просты для самостоятельно реализации такого пула (б)строго документированы
Например так:
future<int> f1 = exec(foo, thread_pool1);//будет выполняться в пуле потоков №1
future<int> f2 = exec(foo, thread_pool2);//будет выполняться в пуле потоков №2


— Чтобы на обьекте future<> можно было "ожидать". Как с таймаутом, так и без. И, очень желательно, без "busy waiting".
future<int> f1 = exec(foo);
....
if( f1.wait(1000) /*ждем секунду*/ ) 
{
    std::cout << f1.get() << std::endl;
} else {
    std::cout << "Не дождались"  << std::endl;
}
__________
16.There is no cause so right that one cannot find a fool following it.
Re[2]: [c++] futures
От: alexeiz  
Дата: 07.03.06 22:10
Оценка:
Здравствуйте, 0xDEADBEEF, Вы писали:

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


A>>Небольшая библиотечка, предоставляющая возможность асинхронного выполнения задач.


DEA>Достаточно неплохо. Но хотелось бы:


DEA>- Независимости. То есть, чтобы эта штука работала на любом пуле потоков. Причем, свойства пула должны быть (а)достаточно просты для самостоятельно реализации такого пула (б)строго документированы

DEA>Например так:
DEA>
DEA>future<int> f1 = exec(foo, thread_pool1);//будет выполняться в пуле потоков №1
DEA>future<int> f2 = exec(foo, thread_pool2);//будет выполняться в пуле потоков №2
DEA>


Так элементарно же:
atl_thread_pool_executor pool1;
atl_thread_pool_executor pool2;

future<int> f1 = pool1(foo);
future<int> f2 = pool2(foo);


Сами пулы реализовывать несложно. Вся вспомогательная функциональность уже есть. А конкретный executor — это просто надстройка. Если посмотреть файл atl_thread_pool_executor.hpp, там буквально два класса, по одной функции в каждом. Я на досуге собираюсь еще и win32 пул сделать.

DEA>- Чтобы на обьекте future<> можно было "ожидать". Как с таймаутом, так и без. И, очень желательно, без "busy waiting".

DEA>
DEA>future<int> f1 = exec(foo);
DEA>....
DEA>if( f1.wait(1000) /*ждем секунду*/ ) 
DEA>{
DEA>    std::cout << f1.get() << std::endl;
DEA>} else {
DEA>    std::cout << "Не дождались"  << std::endl;
DEA>}
DEA>


Просто ожидать можно. Эта функциональность объеденена с запросом результата. Т.е.:
    int result = f1();  // wait for completion and get the result

С таймаутом пока нельзя. Но скоро будет. Думаю сделать интерфейс ввиде логических операций. На данный момент уже возможно такое:
    if (f1)  // non-blocking check for comletion (e.g. try_wait)
    { ... }

С таймаутом будет так:
    if (f1 || timeout(1000))  // whatever happens first, f1 completes or timeout
    { ... }

    if (f1 || f2 || timeout(1000))  // first of the three
    { ... }

    if (f1 && f2 || timeout(1000))  // f1 *and* f2 should both complete or timeout
    { ... }
Re: [c++] futures
От: alexeiz  
Дата: 08.03.06 11:33
Оценка:
Пофиксил баг связанный с живучестью асинхронного объекта. Сделал atl_thread_pool_executor copy-constructible.

http://rsdn.ru/File/15955/futures_redist.zip
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.