подскажите пожалуйста как создать класс, который на вход принимает функцию или метод класса и запускает, останавливает поток. Тоесть некая обертка над потоком.
class Some {
private:
void func2 (void *);
void func3 (void *);
Thread thread2;
Thread thread3;
public :
Some : thread2(&func2, this), thread3 (&func3, this)
{
thread2.start();
thread3.start();
}
~Some
{
thread2.stop();
thread3.stop();
}
}
тоесть еще хотелось бы чтоб Thread работал и с функциями и с методами классов (очевидно для этого ему нужен будет класс, который инкапсулирует в себе эти возможности — в идеале бы
чтоб класс был шаблонный и можно было бы задавать разные аргументы и выходные параметры
Здравствуйте, k732, Вы писали:
K>тоесть на сколько я понял K>1.Thread хочет на вход функцию K>void (*func)(void *) K>2.Нужно наследоваться от Thread и перекрывать Execute
K>но тогда у одного класса может быть только один поток
K>а хотелось бы, чтоб этому классу можно мыло натровить любую функцию K>как K>void (*func)(void *) K>так и K>void Class::func (void *)
K>тоесть еще хотелось бы чтоб Thread работал и с функциями и с методами классов (очевидно для этого ему нужен будет класс, который инкапсулирует в себе эти возможности — в идеале бы K>чтоб класс был шаблонный и можно было бы задавать разные аргументы и выходные параметры
судя по описанию, Вам нужно взять boost::function и наслаждаться жизнью дока на boost::function
Здравствуйте, _Dreamer, Вы писали:
K>>тоесть еще хотелось бы чтоб Thread работал и с функциями и с методами классов (очевидно для этого ему нужен будет класс, который инкапсулирует в себе эти возможности — в идеале бы K>>чтоб класс был шаблонный и можно было бы задавать разные аргументы и выходные параметры
_D>судя по описанию, Вам нужно взять boost::function и наслаждаться жизнью _D>дока на boost::function
ну его boost::function можно использовать например внутри класса-функции, который идет на вход классу-потоку
или Вы имели ввиду что-то другое ?
может boost::function + boost::thread + boost::bind?
Ну ты еще раз внимательно посмотри. Там все так и есть. Только это абстрактный класс.
Наследоваться не нужно — вернее, нужно класс имплементации написать (скажем, в ThreadImpl::Execute должна зваться _beginthreadex) )). Или убери virtual из объявлеиня функций, и сделай его классом реализации. Добавь шаблонный конструктор или шаблонный Execute, если не хочешь ThreadFuncImpl пользоваться.
Re[5]: класс-поток
От:
Аноним
Дата:
07.08.06 07:28
Оценка:
Здравствуйте, k732, Вы писали:
K>>>тоесть еще хотелось бы чтоб Thread работал и с функциями и с методами классов (очевидно для этого ему нужен будет класс, который инкапсулирует в себе эти возможности — в идеале бы K>>>чтоб класс был шаблонный и можно было бы задавать разные аргументы и выходные параметры
_D>>судя по описанию, Вам нужно взять boost::function и наслаждаться жизнью _D>>дока на boost::function
K>ну его boost::function можно использовать например внутри класса-функции, который идет на вход классу-потоку
K>или Вы имели ввиду что-то другое ?
Наверно в объект boost::function (функтор) надо запихнуть искомый вызов функции/класса при создании (при этом функтор должен создаваься динамически), после чего функтор передается в класс потока, который его уже асинхронно обрабатывает (т.е. исполняет в нужное время и внужном месте)
Здравствуйте, k732, Вы писали:
K>ну его boost::function можно использовать например внутри класса-функции, который идет на вход классу-потоку K>или Вы имели ввиду что-то другое ?
ну да, я об этом.
K>может boost::function + boost::thread + boost::bind?
если Вам охота именно такую связку — можно придумать вот такое —
thread_runner был придуман, чтобы избежать передачи this в boost::bind, как у Вас было —
class Some {
public :
Some : thread2(&func2, this), thread3 (&func3, this) {...}
}
если мне склероз не изменяет, это UB.
если нужно иметь несколько потоков, то для этого вроде boost::thread_group придуман.
а вот остановку потока я бы сделал руками, внутри самой функции потока.
тоесть работать пока не было события, или отработать и ждать события, тут от задачи зависит.
Здравствуйте, k732, Вы писали:
K>тоесть еще хотелось бы чтоб Thread работал и с функциями и с методами классов (очевидно для этого ему нужен будет класс, который инкапсулирует в себе эти возможности — в идеале бы K>чтоб класс был шаблонный и можно было бы задавать разные аргументы и выходные параметры
с этим то проблем как раз нет... желаемое тобой уже было реализовано (подозреваю даже не раз ...
тебе прежде всего стоит задуматься над реализацией cancellation pointов и вызовом дестукторов в насильственно убиваемых thread'ах
не сделав этого (в своей библе) ты имеешь 100%ный шанс (в коде сложнее чем multithreaded-hello-world) ОГРЕСТИ ПО ПОЛНОЙ ПРОГРАММЕ!
отладчик буит единственной прогой в которой ты буишь сидеть неделями и концов буит не найти...
Здравствуйте, g_i, Вы писали:
g_i>Ну ты еще раз внимательно посмотри. Там все так и есть. Только это абстрактный класс. g_i>Наследоваться не нужно — вернее, нужно класс имплементации написать (скажем, в ThreadImpl::Execute должна зваться _beginthreadex) )). Или убери virtual из объявлеиня функций, и сделай его классом реализации. Добавь шаблонный конструктор или шаблонный Execute, если не хочешь ThreadFuncImpl пользоваться.
я правильно понял ? только прототип функции поменять нельзя ?
а теперь я так понял его на вход потоку
class Thread {
private :
boost::shared_ptr <CallerImpl> m_caller;
public :
Thread (const boost::shared_ptr<Caller>& caller)
~Thread();
}
но как Thread-у ждать завершение потоковой функции. Можно INFINITE, но кто-то должет например взводить и сбразывать флаг по-которому
нужно выходить из функции.
Здравствуйте, k732, Вы писали:
K>но как Thread-у ждать завершение потоковой функции. Можно INFINITE, но кто-то должет например взводить и сбразывать флаг по-которому K>нужно выходить из функции.
а это правильный вопрос!
подумай еще вот над чем: что буит если твой thread застранет в lock'e (на неопределенное (долгое) время) -- как ты его завершишь в таком случе?
Здравствуйте, zaufi, Вы писали:
Z>Здравствуйте, k732, Вы писали:
K>>тоесть еще хотелось бы чтоб Thread работал и с функциями и с методами классов (очевидно для этого ему нужен будет класс, который инкапсулирует в себе эти возможности — в идеале бы K>>чтоб класс был шаблонный и можно было бы задавать разные аргументы и выходные параметры
Z>с этим то проблем как раз нет... желаемое тобой уже было реализовано (подозреваю даже не раз ... Z>тебе прежде всего стоит задуматься над реализацией cancellation pointов и вызовом дестукторов в насильственно убиваемых thread'ах Z>не сделав этого (в своей библе) ты имеешь 100%ный шанс (в коде сложнее чем multithreaded-hello-world) ОГРЕСТИ ПО ПОЛНОЙ ПРОГРАММЕ! Z>отладчик буит единственной прогой в которой ты буишь сидеть неделями и концов буит не найти...
Здравствуйте, zaufi, Вы писали:
Z>Здравствуйте, k732, Вы писали:
K>>но как Thread-у ждать завершение потоковой функции. Можно INFINITE, но кто-то должет например взводить и сбразывать флаг по-которому K>>нужно выходить из функции.
Z>а это правильный вопрос! Z>подумай еще вот над чем: что буит если твой thread застранет в lock'e (на неопределенное (долгое) время) -- как ты его завершишь в таком случе?
ну и разумеется если ты его таки сможешь убить... вызовутся ли деструкторы для объектов там созданных ?
Здравствуйте, k732, Вы писали:
K>Здравствуйте, zaufi, Вы писали:
Z>>Здравствуйте, k732, Вы писали:
K>>>тоесть еще хотелось бы чтоб Thread работал и с функциями и с методами классов (очевидно для этого ему нужен будет класс, который инкапсулирует в себе эти возможности — в идеале бы K>>>чтоб класс был шаблонный и можно было бы задавать разные аргументы и выходные параметры
Z>>с этим то проблем как раз нет... желаемое тобой уже было реализовано (подозреваю даже не раз ... Z>>тебе прежде всего стоит задуматься над реализацией cancellation pointов и вызовом дестукторов в насильственно убиваемых thread'ах Z>>не сделав этого (в своей библе) ты имеешь 100%ный шанс (в коде сложнее чем multithreaded-hello-world) ОГРЕСТИ ПО ПОЛНОЙ ПРОГРАММЕ! Z>>отладчик буит единственной прогой в которой ты буишь сидеть неделями и концов буит не найти...
K>а можно подробнее — где могут быть грабли
ПОВСЮДУ! и в самых неожиданных местах
--
основная твоя проблема на данный момент: нада научиться безопастно убивать thread -- т.е. так чтоб при его убийстве у тя не было ликов (памяти, дескрипторов, и еще черт знает чего) -- вобщем не освобожденных ресурсов... чтобы при убийстве не оставалось залоченых mutexов (или иных объектов синхроницации)... и т.д. и т.п. (сам додумай
Здравствуйте, zaufi, Вы писали:
Z>>а это правильный вопрос! Z>>подумай еще вот над чем: что буит если твой thread застранет в lock'e (на неопределенное (долгое) время) -- как ты его завершишь в таком случе?
Z>ну и разумеется если ты его таки сможешь убить... вызовутся ли деструкторы для объектов там созданных ?
что-то Вы меня прям пугаете ... Ведь наверняка есть обкатанные методики
Здравствуйте, k732, Вы писали:
K>Здравствуйте, zaufi, Вы писали:
Z>>>а это правильный вопрос! Z>>>подумай еще вот над чем: что буит если твой thread застранет в lock'e (на неопределенное (долгое) время) -- как ты его завершишь в таком случе?
Z>>ну и разумеется если ты его таки сможешь убить... вызовутся ли деструкторы для объектов там созданных ?
K>что-то Вы меня прям пугаете ... Ведь наверняка есть обкатанные методики
ты в стандарте денить видел описание того как вызываются деструкторы в thread'ах??
можешь не листать -- там этого НЕТ
как правило (исключения таки есть реализация threadов (системнозависимая надо заметить) НИЧЕГО не знает о твоих объектах С++!
Здравствуйте, zaufi, Вы писали:
Z>ты в стандарте денить видел описание того как вызываются деструкторы в thread'ах?? Z>можешь не листать -- там этого НЕТ Z>как правило (исключения таки есть реализация threadов (системнозависимая надо заметить) НИЧЕГО не знает о твоих объектах С++!
Здравствуйте, zaufi, Вы писали:
Z>Здравствуйте, k732, Вы писали:
K>>Здравствуйте, zaufi, Вы писали:
Z>>>Здравствуйте, k732, Вы писали:
K>>>>тоесть еще хотелось бы чтоб Thread работал и с функциями и с методами классов (очевидно для этого ему нужен будет класс, который инкапсулирует в себе эти возможности — в идеале бы K>>>>чтоб класс был шаблонный и можно было бы задавать разные аргументы и выходные параметры
Z>>>с этим то проблем как раз нет... желаемое тобой уже было реализовано (подозреваю даже не раз ... Z>>>тебе прежде всего стоит задуматься над реализацией cancellation pointов и вызовом дестукторов в насильственно убиваемых thread'ах Z>>>не сделав этого (в своей библе) ты имеешь 100%ный шанс (в коде сложнее чем multithreaded-hello-world) ОГРЕСТИ ПО ПОЛНОЙ ПРОГРАММЕ! Z>>>отладчик буит единственной прогой в которой ты буишь сидеть неделями и концов буит не найти...
K>>а можно подробнее — где могут быть грабли
Z>ПОВСЮДУ! и в самых неожиданных местах Z>-- Z>основная твоя проблема на данный момент: нада научиться безопастно убивать thread -- т.е. так чтоб при его убийстве у тя не было ликов (памяти, дескрипторов, и еще черт знает чего) -- вобщем не освобожденных ресурсов... чтобы при убийстве не оставалось залоченых mutexов (или иных объектов синхроницации)... и т.д. и т.п. (сам додумай
чесно говоря что-то я повелся на дискуссию
мне кажется что объект-поток должен отвечать только за корректный запуск и остановку потока. А "чтоб при его убийстве у тя не было ликов (памяти, дескрипторов, и еще черт знает чего)" это не его проблеммы, а проблеммы разработчика самой потоковой функции. Ведь системной _beginthreadex это тоже по барабану
Здравствуйте, k732, Вы писали:
K>мне кажется что объект-поток должен отвечать только за корректный запуск и остановку потока. А "чтоб при его убийстве у тя не было ликов (памяти, дескрипторов, и еще черт знает чего)" это не его проблеммы, а проблеммы разработчика самой потоковой функции. Ведь системной _beginthreadex это тоже по барабану
корректный с чьей точки зрения? -- системы наплевавшей на кучу объектов нуждающихся в нетривиальном удалении?
такой подход тоже имеет право на существование -- вот поэтому мне и не нравятся бустерные threadы (и многие другие библы по сути являющиеся wapperами (разной степени корявости) над системными Сишными функциями)
разумееца программер должен следить за кучей всего в своей проге (вместа того чтоб сконцентрироватся над задачей ) -- но это не наш way
в эру когда на нас надвигаются multicorные камни проги просто обязаны уметь пользовать все доступные CPU при этом если написание таких прог останется на текущем уровне то это буит ПРОГРАММЕРСКИЙ АД -- ну согласись кодя на С++ ты должен помнить и следить еще за такими тривиальными вещами как вызов деструкторов, отслеживать последовательность создания/удаления оберток над mutex/condition/thread в дадамемберах своего класса (помня о том кто и как это использует) -- все это требует упрощения!
я для себя лична выбрал way когда эти проблемы максимально переносятся с плеч прогаммера на плечи компилятора + threads implementation -- и на протяжении 3х лет успешно этим решением пользуюсь