[ANN] The Future of Concurrency in C++
От: remark Россия http://www.1024cores.net/
Дата: 04.05.08 19:01
Оценка: 70 (10)
Глядим коротко, что нас, пользователей С/С++, ждёт нового в С++0x относительно поддержки многопоточности:
http://www.justsoftwaresolutions.co.uk/files/future_of_concurrency.pdf

Описываются:
— Модель памяти (memory model)
— Атомарные операции (atomics)
— Локальные для потока переменные (thread-local static variables)
— Потоки (threads)
— Мьютексы (mutexes)
— Условные перменные (condition variables)
— Однократная инициализация (one-time initialization)
— Асинхронные операции (futures)

Так же описывается, что нас ждёт в более отдалённом будущем (в boost, будем надеятся значительно раньше):
— Пулы потоков (thread pools)
— Многопоточные контейнеры (concurrent_queue, concurrent_stack и т.д.)
— Параллельные алгоритмы (parallel_for, parallel_sort и т.д.)
— Транзакционная память и автоматическое распараллеливание (software transactional memory, auto-parallelisation)



1024cores — all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re: Реализация передачи владения на С++0x
От: remark Россия http://www.1024cores.net/
Дата: 04.05.08 19:25
Оценка: 13 (1)
Здравствуйте, remark, Вы писали:

R>Глядим коротко, что нас, пользователей С/С++, ждёт нового в С++0x относительно поддержки многопоточности:



Недавно был вопрос по поводу реализации простейшего паттерна в С++:
http://gzip.rsdn.ru/forum/message/2909622.1.aspx
Автор: NightWind
Дата: 09.04.08


Реализация достаточно не тривиальная + не портируемая:
http://gzip.rsdn.ru/forum/message/2911323.1.aspx
Автор: remark
Дата: 10.04.08



На С++0х это будет реализовываться таким (уже портабельным) способом:
#include <cstdatomic>
#include <vector>
#include <iostream>

std::atomic_bool g_data_init;
std::vector<int> g_data

void tread1()
{
    g_data.push_back(0);
    g_data_init.store(true, std::memory_model_release);
}

void tread2()
{
    while (false == g_data_init.load(std::memory_model_acquire)) {}
    std::cout << g_data[0];
}



R>


1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re: [ANN] The Future of Concurrency in C++
От: Аноним  
Дата: 05.05.08 06:33
Оценка:
Здравствуйте, remark, Вы писали:

R>Глядим коротко, что нас, пользователей С/С++, ждёт нового в С++0x относительно поддержки многопоточности:


а интересно, будет ли вообще С++0x ?
просто "что нас ждёт нового в С++0x" — такая басянистая фраза, что уже не помню она появилась раньше или "что нас ждёт нового в Duke Nukem Forever"

может правильно надо писать "что нас ждёт нового в С++хx" ?
Re[2]: [ANN] The Future of Concurrency in C++
От: Roman Odaisky Украина  
Дата: 05.05.08 06:41
Оценка: :)
Здравствуйте, Аноним, Вы писали:

R>>Глядим коротко, что нас, пользователей С/С++, ждёт нового в С++0x относительно поддержки многопоточности:


А>а интересно, будет ли вообще С++0x ?


C++09. И нииcensored.
До последнего не верил в пирамиду Лебедева.
Re[3]: [ANN] The Future of Concurrency in C++
От: Аноним  
Дата: 05.05.08 08:24
Оценка:
Здравствуйте, Roman Odaisky, Вы писали:

RO>C++09. И нииcensored.


ну да, последний шанс для стандарта 0х
а значит принимать его прийдётся в спешке
Re: [ANN] The Future of Concurrency in C++
От: s.ts  
Дата: 05.05.08 08:48
Оценка:
Я так понимаю, ожидания нескольких событий ( по типу WaitForMultipleObjects ) не будет ?


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

R>Глядим коротко, что нас, пользователей С/С++, ждёт нового в С++0x относительно поддержки многопоточности:

R>http://www.justsoftwaresolutions.co.uk/files/future_of_concurrency.pdf

R>Описываются:

R> — Модель памяти (memory model)
R> — Атомарные операции (atomics)
R> — Локальные для потока переменные (thread-local static variables)
R> — Потоки (threads)
R> — Мьютексы (mutexes)
R> — Условные перменные (condition variables)
R> — Однократная инициализация (one-time initialization)
R> — Асинхронные операции (futures)

R>Так же описывается, что нас ждёт в более отдалённом будущем (в boost, будем надеятся значительно раньше):

R> — Пулы потоков (thread pools)
R> — Многопоточные контейнеры (concurrent_queue, concurrent_stack и т.д.)
R> — Параллельные алгоритмы (parallel_for, parallel_sort и т.д.)
R> — Транзакционная память и автоматическое распараллеливание (software transactional memory, auto-parallelisation)


R>
Re[2]: [ANN] The Future of Concurrency in C++
От: remark Россия http://www.1024cores.net/
Дата: 05.05.08 09:03
Оценка:
Здравствуйте, Аноним, Вы писали:

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


R>>Глядим коротко, что нас, пользователей С/С++, ждёт нового в С++0x относительно поддержки многопоточности:


А>а интересно, будет ли вообще С++0x ?

А>просто "что нас ждёт нового в С++0x" — такая басянистая фраза, что уже не помню она появилась раньше или "что нас ждёт нового в Duke Nukem Forever"

А>может правильно надо писать "что нас ждёт нового в С++хx" ?



Это ещё более басянистая фраза


Если действительно интрересно, то попробуй последить за работой WG21 — там всё открыто.



1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[2]: [ANN] The Future of Concurrency in C++
От: remark Россия http://www.1024cores.net/
Дата: 05.05.08 09:08
Оценка: 9 (2) +2 :))) :))
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on RSDN, USENET and in e-mail?

А как её реализовывать без поддержки ОС?

Хотя бы потому что в POSIX её нет.

Я думаю, что нет.

Здравствуйте, s.ts, Вы писали:

ST>Я так понимаю, ожидания нескольких событий ( по типу WaitForMultipleObjects ) не будет ?


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


R>>Глядим коротко, что нас, пользователей С/С++, ждёт нового в С++0x относительно поддержки многопоточности:

R>>http://www.justsoftwaresolutions.co.uk/files/future_of_concurrency.pdf

R>>Описываются:

R>> — Модель памяти (memory model)
R>> — Атомарные операции (atomics)
R>> — Локальные для потока переменные (thread-local static variables)
R>> — Потоки (threads)
R>> — Мьютексы (mutexes)
R>> — Условные перменные (condition variables)
R>> — Однократная инициализация (one-time initialization)
R>> — Асинхронные операции (futures)

R>>Так же описывается, что нас ждёт в более отдалённом будущем (в boost, будем надеятся значительно раньше):

R>> — Пулы потоков (thread pools)
R>> — Многопоточные контейнеры (concurrent_queue, concurrent_stack и т.д.)
R>> — Параллельные алгоритмы (parallel_for, parallel_sort и т.д.)
R>> — Транзакционная память и автоматическое распараллеливание (software transactional memory, auto-parallelisation)


R>>

1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[3]: [ANN] The Future of Concurrency in C++
От: Roman Odaisky Украина  
Дата: 05.05.08 10:32
Оценка: 6 (1)
А как же select?

R>Хотя бы потому что в POSIX её нет.


R>Я думаю, что нет.


ST>>Я так понимаю, ожидания нескольких событий ( по типу WaitForMultipleObjects ) не будет ?
До последнего не верил в пирамиду Лебедева.
Re[4]: [ANN] The Future of Concurrency in C++
От: dip_2000 Россия  
Дата: 05.05.08 10:34
Оценка:
Здравствуйте, Roman Odaisky, Вы писали:

RO>А как же select?


AFAIK, он может значительно меньше чем WFMO.
Re[5]: [ANN] The Future of Concurrency in C++
От: Roman Odaisky Украина  
Дата: 05.05.08 10:56
Оценка:
Здравствуйте, dip_2000, Вы писали:

RO>>А как же select?


_>AFAIK, он может значительно меньше чем WFMO.


Что именно не умеет select(2) такого, что умеет WaitForMultipleObjects? (Впрочем, обе они кривые, хотя бы потому, что у них слишком сильное ограничение на количество событий.)
До последнего не верил в пирамиду Лебедева.
Re[6]: [ANN] The Future of Concurrency in C++
От: dip_2000 Россия  
Дата: 05.05.08 11:04
Оценка:
Здравствуйте, Roman Odaisky, Вы писали:

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


RO>>>А как же select?


_>>AFAIK, он может значительно меньше чем WFMO.


RO>Что именно не умеет select(2) такого, что умеет WaitForMultipleObjects? (Впрочем, обе они кривые, хотя бы потому, что у них слишком сильное ограничение на количество событий.)

Признаться не линуксоид я ни разу, но когда рассказывал линуксоидам что может WFMO они кусали локти (не надо холивара! у POSIX есть свои плюсы)
Потоков дожидаться по хендлу, процессов.

The WaitForMultipleObjects function can specify handles of any of the following object types in the lpHandles array:

Change notification
Console input
Event
Job
Memory resource notification
Mutex
Process
Semaphore
Thread
Waitable timer

Добавлю что всех, или любого. В любых комбинациях

Re[7]: [ANN] The Future of Concurrency in C++
От: Roman Odaisky Украина  
Дата: 05.05.08 14:31
Оценка:
Здравствуйте, dip_2000, Вы писали:

RO>>Что именно не умеет select(2) такого, что умеет WaitForMultipleObjects? (Впрочем, обе они кривые, хотя бы потому, что у них слишком сильное ограничение на количество событий.)

_>Признаться не линуксоид я ни разу, но когда рассказывал линуксоидам что может WFMO они кусали локти :) (не надо холивара! у POSIX есть свои плюсы)
_>Потоков дожидаться по хендлу, процессов.
_>Добавлю что всех, или любого. В любых комбинациях

Понятно. Это древний флеймообразователь. Основные аргументы — «а мы вот так умеем» и «вот так — это антипаттерн».

Я считаю, что идея WFMO изначально нехороша. Как кто-то где-то сказал, мьютексы, условия и т. п. — это кровати, в которых спят потоки. А спать надлежит в одной кровати, если только речь не об экс-президенте США.

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

Впрочем, функция ожидания одного из многих событий тоже нужна — в ситуациях, когда нельзя/сложно напрямую договориться с генератором этих событий (например, когда они сидят в ядре). Поэтому и существует select (и более продвинутые разновидности вроде epoll и kqueue). Собственно, используя асинхронный В/В, можно даже здесь отказаться от подобных функций, но такое решение попросту сильно потеряет в эффективности.
До последнего не верил в пирамиду Лебедева.
Re[4]: [ANN] The Future of Concurrency in C++
От: jazzer Россия Skype: enerjazzer
Дата: 05.05.08 17:43
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, Roman Odaisky, Вы писали:


RO>>C++09. И нииcensored.


А>ну да, последний шанс для стандарта 0х

А>а значит принимать его прийдётся в спешке

Вообе-то есть четкий график, когда и что.
И, как жалуется Строуструп, если бы не бюрократия, которая царит в ISO, стандарты бы принимались гораздо быстрее.
По его оценкам, стандарт будет готов осенью 2008-го года (финальная версия), а потом около года проваландается по инстанциям до официального издания.
Т.е. к моменту официального выхода комитет уже год как будет работать над TR2.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[8]: [ANN] The Future of Concurrency in C++
От: remark Россия http://www.1024cores.net/
Дата: 05.05.08 18:08
Оценка:
Здравствуйте, Roman Odaisky, Вы писали:

RO>Я считаю, что идея WFMO изначально нехороша. Как кто-то где-то сказал, мьютексы, условия и т. п. — это кровати, в которых спят потоки. А спать надлежит в одной кровати, если только речь не об экс-президенте США.


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

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


А почему первый подход плохой?



1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[8]: [ANN] The Future of Concurrency in C++
От: Left2 Украина  
Дата: 05.05.08 18:27
Оценка: +2
RO>Я считаю, что идея WFMO изначально нехороша. Как кто-то где-то сказал, мьютексы, условия и т. п. — это кровати, в которых спят потоки. А спать надлежит в одной кровати, если только речь не об экс-президенте США.
Не всё понял. Тебе не нравится то что WFMO позволяет блокироваться не только на потоках ввода-вывода, а ещё и на мьютексах, семафорах и т.п.? Или не нравится вообще подход "ждать более чем один обьект синхронизации"?

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

RO>Идеологически правильный подход — на тебе коллбек, когда что-нибудь интересное произойдет, звякни (а коллбек дернет условие на стороне ожидающего потока).
Хм. А в чём разница? Реально в прикладном коде это всё равно будет обёрнуто в реактор (который к тому же абстрагируется от того что там под капотом — WFMO или select) который в итоге дёрнет именно коллбек с тем контекстом который с ним ассоциирован. А отдавать настоящие колбеки в функцию синхронизации... Не знаю, мне не нравится Ну или по крайней мере, не вижу явных преимуществ.
... << RSDN@Home 1.2.0 alpha rev. 717>>
Re[9]: [ANN] The Future of Concurrency in C++
От: Roman Odaisky Украина  
Дата: 05.05.08 19:01
Оценка:
Здравствуйте, remark, Вы писали:

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

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

R>А почему первый подход плохой?


(Главное) Выставляет наружу объекты синхронизации.
Сигналит даже тогда, когда никто не слушает.
Требует WaitForMultipleObjects или велосипед.
Поди разбери, что именно сработало (недостаток именно WFMO, а не подхода).
Строгие ограничения на количество объектов (недостаток именно WFMO, а не подхода).
Относительный таймаут (недостаток именно WFMO, а не подхода).

Я поискал немного по RSDN, все увиденные мной упоминания WFMO, кроме одного, были связаны с ожиданием завершения N-ного числа потоков. Хотя это то же самое, что дожидаться завершения по одному.

Приведи пример кода, который использует WaitForMultipleObjects и без него никак не обойдется.
До последнего не верил в пирамиду Лебедева.
Re[9]: [ANN] The Future of Concurrency in C++
От: Roman Odaisky Украина  
Дата: 05.05.08 19:57
Оценка:
Здравствуйте, Left2, Вы писали:

RO>>Я считаю, что идея WFMO изначально нехороша. Как кто-то где-то сказал, мьютексы, условия и т. п. — это кровати, в которых спят потоки. А спать надлежит в одной кровати, если только речь не об экс-президенте США.

L>Тебе не нравится то что WFMO позволяет блокироваться не только на потоках ввода-вывода, а ещё и на мьютексах, семафорах и т.п.?

Это может не нравиться только Шеридану :-)

L>Или не нравится вообще подход "ждать более чем один обьект синхронизации"?


А вот подход, наверное, неправильный.

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

RO>>Идеологически правильный подход — на тебе коллбек, когда что-нибудь интересное произойдет, звякни (а коллбек дернет условие на стороне ожидающего потока).
L>Хм. А в чём разница? Реально в прикладном коде это всё равно будет обёрнуто в реактор (который к тому же абстрагируется от того что там под капотом — WFMO или select) который в итоге дёрнет именно коллбек с тем контекстом который с ним ассоциирован. А отдавать настоящие колбеки в функцию синхронизации... Не знаю, мне не нравится :) Ну или по крайней мере, не вижу явных преимуществ.

Это немножко другое. select, poll, epoll, kqueue, IOCP — это демультиплексоры. Они выбирают подмножество интересных дескрипторов из (потенциально большого) множества.

Речь о (проблемном) подходе, в котором события, на которых можно блокироваться, выставляются как часть интерфейса.
До последнего не верил в пирамиду Лебедева.
Re[10]: [ANN] The Future of Concurrency in C++
От: Left2 Украина  
Дата: 05.05.08 20:25
Оценка:
L>>Хм. А в чём разница? Реально в прикладном коде это всё равно будет обёрнуто в реактор (который к тому же абстрагируется от того что там под капотом — WFMO или select) который в итоге дёрнет именно коллбек с тем контекстом который с ним ассоциирован. А отдавать настоящие колбеки в функцию синхронизации... Не знаю, мне не нравится Ну или по крайней мере, не вижу явных преимуществ.

RO>Это немножко другое. select, poll, epoll, kqueue, IOCP — это демультиплексоры. Они выбирают подмножество интересных дескрипторов из (потенциально большого) множества.

Так и WFMO — точно такой же демультиплексор, с чуть другим (даже не принципиально другим, а просто чуть другим) интерфейсом.

RO>Речь о (проблемном) подходе, в котором события, на которых можно блокироваться, выставляются как часть интерфейса.

Всё равно не пойму. При чём тут сам WFMO тогда? И что плохого в том что события выставляются как часть интерфейса? В грамотно спроектированной системе всё равно это будет в виде "вот это событие говорит о том что в очереди заданий появилось новое задание, а вот это говорит о том что нужно завершить работу и потушиться". Чем это принципиально отличается от "дёрни меня за эту функцию в случае 1, и вот за эту в случае 2"? Или я неправильно понял твою идею насчёт коллбеков?
... << RSDN@Home 1.2.0 alpha rev. 717>>
Re[4]: [ANN] The Future of Concurrency in C++
От: NikeByNike Россия  
Дата: 05.05.08 20:31
Оценка: :)
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, Roman Odaisky, Вы писали:


RO>>C++09. И нииcensored.


А>ну да, последний шанс для стандарта 0х

А>а значит принимать его прийдётся в спешке

Ну почему же, может быть ещё С++0A, C++0B, C++0xDEADBEEF в конце концов.
Нужно разобрать угил.
Re: [ANN] The Future of Concurrency in C++
От: Аноним  
Дата: 05.05.08 22:24
Оценка:
R>Так же описывается, что нас ждёт в более отдалённом будущем (в boost, будем надеятся значительно раньше):
R> — Пулы потоков (thread pools)
А смысл их отделять от обычных потоков? Если уж ввели некую абстракцию самого потока, то почему бы в имплементации не делать пул потоков или юзать механизм предоставляемый ОС (намекаю на мой любимый QueueUserWorkItem)?

R> — Транзакционная память и автоматическое распараллеливание (software transactional memory, auto-parallelisation)

Второе умеет уже сейчас Intel CPP
Re[10]: [ANN] The Future of Concurrency in C++
От: dip_2000 Россия  
Дата: 06.05.08 04:02
Оценка: +1
Здравствуйте, Roman Odaisky, Вы писали:

RO>(Главное) Выставляет наружу объекты синхронизации.

RO>Сигналит даже тогда, когда никто не слушает.
RO>Требует WaitForMultipleObjects или велосипед.
RO>Поди разбери, что именно сработало (недостаток именно WFMO, а не подхода).
RO>Строгие ограничения на количество объектов (недостаток именно WFMO, а не подхода).
RO>Относительный таймаут (недостаток именно WFMO, а не подхода).

RO>Я поискал немного по RSDN, все увиденные мной упоминания WFMO, кроме одного, были связаны с ожиданием завершения N-ного числа потоков. Хотя это то же самое, что дожидаться завершения по одному.


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

RO>Приведи пример кода, который использует WaitForMultipleObjects и без него никак не обойдется.


Разумееется такого нет Всегда можно сильно или не сильно извратиться и написать код, делающий то же самое. Но после понимания WFMO(или прожигания мозга антинаучным API, для кого как), и его использования, код становится проще, лаконечнее. Можно сказать удобнее в написании для пользователя API.

PS Я абсолютно согласен что идеологически, изначально подход был не оптимальным, и, возможно не лучшим(можно еще порассуждать про "в UNIX все файлы"). НО. То что получилось, при адекватном использовании, крайне удобно.
Re[2]: [ANN] The Future of Concurrency in C++
От: remark Россия http://www.1024cores.net/
Дата: 06.05.08 06:33
Оценка:
Здравствуйте, Аноним, Вы писали:

R>>Так же описывается, что нас ждёт в более отдалённом будущем (в boost, будем надеятся значительно раньше):

R>> — Пулы потоков (thread pools)

А>А смысл их отделять от обычных потоков? Если уж ввели некую абстракцию самого потока, то почему бы в имплементации не делать пул потоков


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


А>или юзать механизм предоставляемый ОС (намекаю на мой любимый QueueUserWorkItem)?


Ну типа они предполагают, что С++ будет работать ещё на паре ОС, кроме Windows.


R>> — Транзакционная память и автоматическое распараллеливание (software transactional memory, auto-parallelisation)


А>Второе умеет уже сейчас Intel CPP


У Intel есть компилятор, который и первое умеет. Только пока, по-моему, от этого никому ни жарко, ни холодно.



1024cores &mdash; all about multithreading, multicore, concurrency, parallelism, lock-free algorithms
Re[11]: [ANN] The Future of Concurrency in C++
От: Roman Odaisky Украина  
Дата: 06.05.08 09:24
Оценка: 1 (1)
Здравствуйте, Left2, Вы писали:

RO>>Речь о (проблемном) подходе, в котором события, на которых можно блокироваться, выставляются как часть интерфейса.

L>Всё равно не пойму. При чём тут сам WFMO тогда? И что плохого в том что события выставляются как часть интерфейса? Чем это принципиально отличается от "дёрни меня за эту функцию в случае 1, и вот за эту в случае 2"?

Во-первых, это сильно вредит портируемости.

Во-вторых, это решение задачи не с той стороны. К примеру, некий поток собирает данные и выставляет событие всякий раз, как доступна новая порция данных. Если ты хочешь обрабатывать эти данные, тебе непременно нужен другой поток, который будет блокироваться на том событии. Что же делать, если у тебя есть, к примеру, атомарная функция, в которую эти данные нужно передавать, не пытаясь кого-нибудь разбудить?

Вот примерно так это выглядит с коллбеками:
class Gatherer
{
public:
    void operator()()
    {
        while(boost::optional<Data> data = readData())
        {
            boost::unique_lock<boost::mutex> lock(m_mutexSignal);
            m_signal(*data);
        }
    }

    boost::signals::connection addCallback(boost::function<void (Data const &)> callback)
    {
        boost::unique_lock<boost::mutex> lock(m_mutexSignal);
        return m_signal.connect(callback);
    }

private:
    boost::mutex m_mutexSignal;
    boost::signal<void (Data const &)> m_signal;
};

class Processor
{
public:
    Processor(): m_shouldStop(false)
    {
    }

    void operator()()
    {
        boost::unique_lock<boost::mutex> lock(m_mutex);

        while(1)
        {
            if(m_shouldStop)
            {
                return;
            }
            if(m_data)
            {
                doSomething(*m_data);
                m_data = boost::none;
            }
            m_ping.wait(lock);
        }
    }

    void incoming(Data const& data)
    {
        boost::unique_lock<boost::mutex> lock(m_mutex);
        m_data = data;
        m_ping.notify_all();
    }

    void stop()
    {
        boost::unique_lock<boost::mutex> lock(m_mutex);
        m_shouldStop = true;
        m_ping.notify_all();
    }

private:
    bool m_shouldStop;
    boost::optional<Data> m_data;

    boost::mutex m_mutex;
    boost::condition_variable_any m_ping;
};

Всё красиво и аккуратно. Синхронизация только там, где нужна. Может быть сколько угодно экземпляров обоих классов. Для демонстрации ожидания двух событий я сделал флаг остановки, хотя на самом деле он не требуется — можно вызвать boost::thread::interrupt() и из ближайшей блокирующей функции вылетит исключение. Т. е., обработчик можно было переписать попросту так:
boost::unique_lock<boost::mutex> lock(m_mutex);
while(1)
{
    m_ping.wait(lock, boost::bind(&boost::optional<Data>::is_initialized, m_data); // или boost::lambda::var(m_data)
    doSomething(*m_data);
    m_data = boost::none;
}

Если же собиратель данных будет выставлять наружу событие, то он должен будет, во-первых, держать у себя backlog данных, которые у него еще не забрали, во-вторых, будет обязательно будить все потоки (в то время как коллбек может принять решение, что эта порция данных ему неинтересна), в-третьих, я не уверен, но выглядит похоже на priority inversion в особо несчастных случаях.

Тем более, что в ядре всё равно где-то находится список тех, кто ожидает наступления данного события, — т. е., набор «коллбеков» всё равно есть, только спрятан! Лучше уж написать его самому так, как надо.
До последнего не верил в пирамиду Лебедева.
Re[12]: [ANN] The Future of Concurrency in C++
От: dip_2000 Россия  
Дата: 06.05.08 10:13
Оценка:
Здравствуйте, Roman Odaisky, Вы писали:

Извиняюсь, что опять вклиниваюсь в дискуссию

RO>Во-первых, это сильно вредит портируемости.

Есть в практике слычаи, когда не только с Винды код переезжает, а и НА нее другие системы не очень заботятся о портируемости многопоточного кода, почему здесь это приводится как минус ?

RO>Во-вторых, это решение задачи не с той стороны.

А вот скажите, с какой стороны надо решать задачу подобного плана :
есть массив структур. для каждой создается массив обработчик. функция потока получает указатель на "свою" структуру. Отрабатывает, изменяет структуру, и поток умирает. Вопрос : зачем тут плодить множество сущностей ? зачем потоку в конце жизни выставлять событие (сигнал, дергать коллбэк)?

//на глазок
struct some_mega_struct{ int i_; };

int ThreadFoo(void* pContext)
{
some_mega_struct* p = static_cast<some_mega_struct*>(pContext);
(pContext->i)++;
return 0;
}


HANDLE hVec[16];
some_mega_struct vec_some_mega_struct[16];


for (size_t i = 0; i != 16; ++i )
hVec[i] = CreateThread(...,&vec_some_mega_struct[i]);

WFMO(sizeof(hVec) ,&hVec[0],); // вот тут дождались


Re[13]: извиняюсь за "стиль"
От: dip_2000 Россия  
Дата: 06.05.08 10:15
Оценка:
Здравствуйте, dip_2000, Вы писали:

писалось для краткой иллюстрации идеи
Re[13]: [ANN] The Future of Concurrency in C++
От: Roman Odaisky Украина  
Дата: 06.05.08 10:53
Оценка:
Здравствуйте, dip_2000, Вы писали:

RO>>Во-первых, это сильно вредит портируемости.

_>Есть в практике слычаи, когда не только с Винды код переезжает, а и НА нее :) другие системы не очень заботятся о портируемости многопоточного кода, почему здесь это приводится как минус ? :xz:

Поинтересуйся как-нибудь, на скольки платформах доступны pthreads и GNU Pth. (Подсказка: «p» — это POSIX.)

RO>>Во-вторых, это решение задачи не с той стороны.

_>А вот скажите, с какой стороны надо решать задачу подобного плана :

_>
_>for (size_t i = 0; i != 16; ++i )
_>hVec[i] = CreateThread(...,&vec_some_mega_struct[i]);
_>WFMO(sizeof(hVec) ,&hVec[0],); // вот тут дождались
_>

Я же специально упомянул этот случай выше по ветке.
С очень простой стороны:
for(std::thread& t : pool) // C++09
{
    t.join();
}

Здесь вполне можно дождаться завершения первого, затем второго и т. д. Тем более, что с высокой вероятностью здесь будет 0—1 системных вызовов (если потоки успеют сделать свое черное дело).
До последнего не верил в пирамиду Лебедева.
Re[14]: [ANN] The Future of Concurrency in C++
От: dip_2000 Россия  
Дата: 06.05.08 13:04
Оценка:
Здравствуйте, Roman Odaisky, Вы писали:

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


RO>>>Во-первых, это сильно вредит портируемости.

_>>Есть в практике слычаи, когда не только с Винды код переезжает, а и НА нее другие системы не очень заботятся о портируемости многопоточного кода, почему здесь это приводится как минус ?

RO>Поинтересуйся как-нибудь, на скольки платформах доступны pthreads и GNU Pth. (Подсказка: «p» — это POSIX.)

Какое уважение к собеседнику Спасибо, поинтересуюсь обязательно.
RO>Я же специально упомянул этот случай выше по ветке.
RO>С очень простой стороны:
RO>
RO>for(std::thread& t : pool) // C++09
RO>{
RO>    t.join();
RO>}
RO>


RO>Здесь вполне можно дождаться завершения первого, затем второго и т. д. Тем более, что с высокой вероятностью здесь будет 0—1 системных вызовов (если потоки успеют сделать свое черное дело).

Это уже не язык для перфоманса, имхо.... Вобщем я получил ответ
Re[5]: [ANN] The Future of Concurrency in C++
От: Roman Odaisky Украина  
Дата: 06.05.08 13:12
Оценка:
Здравствуйте, jazzer, Вы писали:

J>как жалуется Строуструп, если бы не бюрократия, которая царит в ISO, стандарты бы принимались гораздо быстрее.

J>По его оценкам, стандарт будет готов осенью 2008-го года (финальная версия), а потом около года проваландается по инстанциям до официального издания.
J>Т.е. к моменту официального выхода комитет уже год как будет работать над TR2.

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

Интересно, сможет ли комитет в течение того года фиксить баги, которые обнаружат многочисленные «бета-тестеры», или будет складывать их в долгий ящик^W^W^W в TR2?
До последнего не верил в пирамиду Лебедева.
Re[15]: [ANN] The Future of Concurrency in C++
От: Roman Odaisky Украина  
Дата: 06.05.08 14:26
Оценка:
Здравствуйте, dip_2000, Вы писали:

RO>>С очень простой стороны:

RO>>
RO>>for(std::thread& t : pool) // C++09
RO>>{
RO>>    t.join();
RO>>}
RO>>


RO>>Здесь вполне можно дождаться завершения первого, затем второго и т. д. Тем более, что с высокой вероятностью здесь будет 0—1 системных вызовов (если потоки успеют сделать свое черное дело).

_>Это уже не язык для перфоманса, имхо.... Вобщем я получил ответ :beer:

Завершение потока — это частный случай. Хотя бы потому, что поток по определению не может сообщить наружу, что он завершился :-)

Проведи как-нибудь эксперимент:
void f(void *)
{
    Sleep(100);
}

std::vector<HANDLE> pool(N);
for(std::size_t i = 0; i < N; ++i)
{
    pool[i] = (HANDLE)_beginthreadex(0, 0, f, 0, 0, 0);
}

// вариант 1
WaitForMultipleObjects(N, &pool.begin(), TRUE, INFINITE);

// вариант 2
for(std::size_t i = 0; i < N; ++i)
{
    WaitForSingleObject(pool[i], INFINITE);
}

Что выполнится быстрее? Я уверен, что разницы во времени исполнения нет.
До последнего не верил в пирамиду Лебедева.
Re[16]: [ANN] The Future of Concurrency in C++
От: dip_2000 Россия  
Дата: 06.05.08 15:17
Оценка:
Здравствуйте, Roman Odaisky, Вы писали:


RO>Что выполнится быстрее? Я уверен, что разницы во времени исполнения нет.

я уверен что разницы между
++i и i++ в 98% случаев нет, и тем не менее в приличном обществе так не пишут. Думаю по понятным причинам. Код пишется не на 1 частный случай. Этот же код может работать, работать, а потом выстрелить в совершенно других условиях.
Вобщем продолжать смысла нет. Думаю все все поняли
Re[17]: [ANN] The Future of Concurrency in C++
От: Roman Odaisky Украина  
Дата: 06.05.08 15:51
Оценка:
Здравствуйте, dip_2000, Вы писали:

_>я уверен что разницы между

_>++i и i++ в 98% случаев нет, и тем не менее в приличном обществе так не пишут. Думаю по понятным причинам. Код пишется не на 1 частный случай. Этот же код может работать, работать, а потом выстрелить в совершенно других условиях.
_>Вобщем продолжать смысла нет. Думаю все все поняли :-)

Так вот... К чему это я?

В последнем черновике стандарта предусмотрен метод std::thread_group::join_all().

В Boost 1.35 на всех платформах он реализован как join в цикле.

Так что в ногу здесь не выстрелишь.
До последнего не верил в пирамиду Лебедева.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.