Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Вызов callback'а в контексте другого потока 
V
    Опции темы
borisbn
Дата 28.5.2013, 18:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 22
Всего: 135



Здравствуйте.

Есть класс, который получает в конструкторе callback (указатель на функцию или шаблонный параметр типа Callable - не важно) и запускает отдельный поток. При наступлении какого-то события необходимо вызвать callback, но так, чтобы он был вызван в контексте потока, который создал класс. В Windows я могу использовать SendMessage для перехода из рабочего потока в главный, но хотелось бы кроссплатформенного решения, но без Qt (с последним я знаю как сделать то, что хочу).

Код (убрал не имеющее отношение к делу, например деструктор и т.п.) :
Код
struct ThreadWrap {
    ThreadWrap( void(*callback)() )
        : m_thread( & ThreadWrap::treadFunc, this, callback )
    {
        cout << std::this_thread::get_id() << endl; //                  ( 1 )
    }
private:
    std::thread m_thread;
    void treadFunc( void(*callback)() ) {
        while ( ! m_abort ) {
            // при каком-то условии
            callback();
           // эта функция вызовется из моего/рабочего/дополнительного потока,
           // а я хочу, чтобы из потока, создавшего класс ThreadWrap
        }
    }
};

// где-то в другом месте
void foo() {
    cout << std::this_thread::get_id() << endl; //                  ( 2 )
}
ThreadWrap tw( foo );


Другими словами, я хочу, чтобы в ( 1 ) и ( 2 ) напечаталось одно и то же. М.б. в конструкторе этот std::this_thread::get_id() нужно сохранять, но как потом сказать при вызове callback'а что его (callback) нужно вызвать в том самом потоке ?

Спасибо.

Это сообщение отредактировал(а) borisbn - 28.5.2013, 18:42


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
feodorv
Дата 28.5.2013, 19:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 11
Всего: 45



Разве поток, который создал класс, не должен просто дожидаться указанного события, а при его наступлении вызвать callback()?


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
mes
Дата 28.5.2013, 19:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



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

Добавлено через 4 минуты и 51 секунду
конечно можно использовать и синхронную модель, но она в принципе является частным случаем, кода размер очереди равняется единице..



--------------------
PM MAIL WWW   Вверх
xvr
Дата 29.5.2013, 13:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



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

NB. Вызов на стеке-прерывании не рассматриваем. Это можно сделать, но очень черевато неожиданными сломами в самых неожиданных местах.

PM MAIL   Вверх
borisbn
Дата 29.5.2013, 13:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 22
Всего: 135



Всем спасибо за ответы. 

В Windows есть очередь сообщений, через которую можно послать событие о том, что нужно что-то вызвать. В linux, подозреваю, тоже есть нечто подобное. В Qt сделали так, что обращение к этим очередям для меня прозрачно (коннектишь сигнал к слоту и всё), но я не хочу в данном конкретном случае использовать Qt. Была надежда, что либо в C++11 (какой-нибудь std::this_thread::call_from_other) либо в boost (где-нибудь в дебрях asio) либо ещё в какой-нибудь header-only библиотеке это тоже реализовано...
Жаль. Я, конечно, подозревал, что никакой магии не существует, но... надежда умирает последней...

Ещё раз спасибо. Закрываю.


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
mes
Дата 30.5.2013, 17:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(borisbn @  29.5.2013,  12:33 Найти цитируемый пост)
либо в boost (где-нибудь в дебрях asio) 

так асио оно само и есть для этого smile


--------------------
PM MAIL WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1737 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.