Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > C/C++: Общие вопросы > Использование не static метода из разных поток |
Автор: Jawello 20.3.2014, 18:59 |
Доброе время суток. Изучал чужой код и наткнулся на следующее: Создается указатель на объект, объект имеет один метод (назовем его metod), который не работает с внутренними полями класса, только с входящими в метод параметрами (перед ним можно спокойно дописать модификатор static). Этот указатель передается в потоки, и в каждом потоке вызывается указатель на объект->metod(par1, par2). Т.е. каждый из потоков может одновременно обращаться к объекту из кучи и использовать его метод. Возник вопрос: не приведет ли к конфликту такой способ вызова? корректно ли вообще так делать? Если бы метод был статический - я понимаю, что каждый вызов данного метода будет независимый, но как себя будет вести метод в данном случае я не понимаю. спасибо. |
Автор: borisbn 21.3.2014, 09:59 | ||
Jawello, вызов невиртуального метода класса отличается от вызова обычной функции тем, что в него неявно передаётся первым параметром this. В твоём случае
Если метод не использует его (читай не обращается к полям класса), то он, по большому счёту, ничем не отличается от обычной функции. А вот можно ли эту функцию дёргать из разных потоков - вопрос... Не зная, что она делает - трудно сказать. Может файлы открывает... Может к создаёт элементы GUI... |
Автор: Jawello 21.3.2014, 11:26 |
borisbn, спасибо большое! Я не знал, что this передается как не явный параметр. Естественно метод не работает с внешними ресурсами, на вход два параметра по ссылке, и все изменения происходят только с ними. Этот трюк явно используется вместе с полиморфизмом, данный метод виртуальный, что позволяет его перегружать в наследуюемых классах, соответственно для каждого класса будет вызван свой метод. Это очень удобно и мне отлично подходит. Если бы метод был бы статичным, то пергрузить его скорее всего было бы нельзя (на сколько я знаю статический метод не может быть виртуальным) и пришлось бы использовать какую-то мета информацию для вызова нужного метода нужного класса или явно прописывать это, а это крайне не удобно. Еще раз спасибо. |
Автор: Jawello 21.3.2014, 12:21 |
borisbn, возник еще один вопрос: У меня класс, в котором есть поле массив указателей - в разных потоках вызывается метод (который был описан выше) и в зависимости от пришедших в него параметров выбирает один из указателей из массива (который поле класса). Метод ни чего не делает с указателями (не модифицирует их ... указатели указывают на похожие объекты, т.е. у них будет вызван метод, который вообще не обращается к полям класса). Так вот, обращение к такому массиву из разных потоков может привести к коллизии? т.е. нужно ли использовать н-р мьютекс? По идее операция чтения одного ресурса вполне может происходит из различных потоков и ни к чему плохому это не приведет. Но я не уверен. Буду благодарен за разъяснение. Спасибо еще раз) |
Автор: borisbn 21.3.2014, 12:43 |
Jawello, я запутался ))) Приведи (хоть на псевдокоде) минимальный кусок кода, который бы описывал твою ситуацию |
Автор: Jawello 21.3.2014, 13:05 | ||
Я использую Qt.
Как видно из кода: есть базовый класс HttpRequestHandler, у него есть виртуальный метод service. Я его переопределил указанным выше способом. В этом методе я вытаскиваю из QHash указатель на объект класса HttpRequestHandler и в свою очередь вызываю его метод service. Так вот, указатель на объект HttpRequestMapperByPath я передаю в класс, который инициализирует определенное кол-во потоков и в них вызывает метод service класса HttpRequestMapperByPath. Собственно вопрос, не возникнет ли проблем с тем что на все потоки m_responseMap один? ну и не проглядел ли я еще возможные проблемы) |
Автор: borisbn 21.3.2014, 13:34 | ||
Если к моменту первого вызова HttpRequestMapperByPath::service хэш уже будет заполнен и изменяться больше точно не будет, то Qt гарантирует, что
А вот что делается в requestHandler->service(request, response); - трудно сказать... |
Автор: Jawello 21.3.2014, 14:20 |
Спасибо большое) значит все будет нормально работать как я и предполагал. requestHandler->service(request, response); обязуется работать по тем же принципами, что и service его вызывающий. |