| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Общие вопросы > Вызов callback'а в контексте другого потока |
| Автор: borisbn 28.5.2013, 18:37 | ||
| Здравствуйте. Есть класс, который получает в конструкторе callback (указатель на функцию или шаблонный параметр типа Callable - не важно) и запускает отдельный поток. При наступлении какого-то события необходимо вызвать callback, но так, чтобы он был вызван в контексте потока, который создал класс. В Windows я могу использовать SendMessage для перехода из рабочего потока в главный, но хотелось бы кроссплатформенного решения, но без Qt (с последним я знаю как сделать то, что хочу). Код (убрал не имеющее отношение к делу, например деструктор и т.п.) :
Другими словами, я хочу, чтобы в ( 1 ) и ( 2 ) напечаталось одно и то же. М.б. в конструкторе этот std::this_thread::get_id() нужно сохранять, но как потом сказать при вызове callback'а что его (callback) нужно вызвать в том самом потоке ? Спасибо. |
| Автор: feodorv 28.5.2013, 19:29 |
| Разве поток, который создал класс, не должен просто дожидаться указанного события, а при его наступлении вызвать callback()? |
| Автор: mes 28.5.2013, 19:36 |
| чтоб вызвать что то в другом потоке, надо соеденинить оба потока очередью, из котороой целевой поток будет брать что пришло и вызывать это.. Если вы хотите, чтоб в целевом потоке приходяшие события обрабатывались параллельно основной работе, нужно разбить его работу на составлящие, между выполнениями которых опрашивать очередь. Оно же событейная модель с точки зрения кутэ или же асинхронная с точки зрения asio.. Добавлено через 4 минуты и 51 секунду конечно можно использовать и синхронную модель, но она в принципе является частным случаем, кода размер очереди равняется единице.. |
| Автор: xvr 29.5.2013, 13:08 |
| Сформулирую то, что сказал mes немного попроще. Что бы что то вызвать в другом потоке, в этом другом потоке должна быть точка синхронизации - именно в ней и будет произведен вызов этого 'чего то'. Вызвать нечто в совершенно неопределенном месте любого потока невозможно, т.к. при вызове поток должен находится в консистентном состоянии, т.е. ваш вызов должен быть естественным образом вложен в текущий стековый фрейм, а это можно сделать только там, где изначально предусматривался вызов функции. NB. Вызов на стеке-прерывании не рассматриваем. Это можно сделать, но очень черевато неожиданными сломами в самых неожиданных местах. |
| Автор: borisbn 29.5.2013, 13:33 |
| Всем спасибо за ответы. В Windows есть очередь сообщений, через которую можно послать событие о том, что нужно что-то вызвать. В linux, подозреваю, тоже есть нечто подобное. В Qt сделали так, что обращение к этим очередям для меня прозрачно (коннектишь сигнал к слоту и всё), но я не хочу в данном конкретном случае использовать Qt. Была надежда, что либо в C++11 (какой-нибудь std::this_thread::call_from_other) либо в boost (где-нибудь в дебрях asio) либо ещё в какой-нибудь header-only библиотеке это тоже реализовано... Жаль. Я, конечно, подозревал, что никакой магии не существует, но... надежда умирает последней... Ещё раз спасибо. Закрываю. |
| Автор: mes 30.5.2013, 17:44 |
так асио оно само и есть для этого |