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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Использование не static метода из разных поток 
V
    Опции темы
Jawello
Дата 20.3.2014, 18:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Доброе время суток.

Изучал чужой код и наткнулся на следующее:
Создается указатель на объект, объект имеет один метод (назовем его metod), который не работает с внутренними полями класса, только с входящими в метод параметрами (перед ним можно спокойно дописать модификатор static). Этот указатель передается в потоки, и в каждом потоке вызывается указатель на объект->metod(par1, par2). Т.е. каждый из потоков может одновременно обращаться к объекту из кучи и использовать его метод. 
Возник вопрос: не приведет ли к конфликту такой способ вызова? корректно ли вообще так делать?
Если бы метод был статический - я понимаю, что каждый вызов данного метода будет независимый, но как себя будет вести метод в данном случае я не понимаю. 

спасибо. 
PM MAIL   Вверх
borisbn
Дата 21.3.2014, 09:59 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Jawello, вызов невиртуального метода класса отличается от вызова обычной функции тем, что в него неявно передаётся первым параметром this. В твоём случае
Код
объект->metod(par1, par2) === metod(объект, par1, par2)

Если метод не использует его (читай не обращается к полям класса), то он, по большому счёту, ничем не отличается от обычной функции. А вот можно ли эту функцию дёргать из разных потоков - вопрос... Не зная, что она делает - трудно сказать. Может файлы открывает... Может к создаёт элементы GUI... 


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


Новичок



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

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



borisbn, спасибо большое! Я не знал, что this  передается как не явный параметр. Естественно метод не работает с внешними ресурсами, на вход два параметра по ссылке, и все изменения происходят только с ними. Этот трюк явно используется вместе с полиморфизмом, данный метод виртуальный, что позволяет его перегружать в наследуюемых классах, соответственно для каждого класса будет вызван свой метод. Это очень удобно и мне отлично подходит. 
Если бы метод был бы статичным, то пергрузить его скорее всего было бы нельзя (на сколько я знаю статический метод не может быть виртуальным) и пришлось бы использовать какую-то мета информацию для вызова нужного метода нужного класса или явно прописывать это, а это крайне не удобно. 

Еще раз спасибо. 

Это сообщение отредактировал(а) Jawello - 21.3.2014, 11:27
PM MAIL   Вверх
Jawello
Дата 21.3.2014, 12:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



borisbn, возник еще один вопрос:
У меня класс, в котором есть поле массив указателей - в разных потоках вызывается метод (который был описан выше) и в зависимости от пришедших в него параметров выбирает один из указателей из массива (который поле класса). Метод ни чего не делает с указателями (не модифицирует их ... указатели указывают на похожие объекты, т.е. у них будет вызван метод, который вообще не обращается к полям класса). Так вот, обращение к такому массиву из разных потоков может привести к коллизии? т.е. нужно ли использовать н-р мьютекс? 
По идее операция чтения одного ресурса вполне может происходит из различных потоков и ни к чему плохому это не приведет. Но я не уверен. Буду благодарен за разъяснение. 


Спасибо еще раз)
PM MAIL   Вверх
borisbn
Дата 21.3.2014, 12:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Jawello, я запутался )))
Приведи (хоть на псевдокоде) минимальный кусок кода, который бы описывал твою ситуацию


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


Новичок



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

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



Я использую Qt.
Код

class HttpRequestMapperByPath : public HttpRequestHandler
{
    Q_OBJECT
    Q_DISABLE_COPY(HttpRequestMapperByPath)
public:
    HttpRequestMapperByPath(QObject* parent=0);

    ~HttpRequestMapperByPath();

    virtual void service(HttpRequest& request,
                 HttpResponse& response); // данный метод будет вызываться из разных потоков

private:
    static QString prepareServicePath(const QString& n_servicePath);
private:
    QHash<QString, HttpRequestHandler*> m_responseMap;
};

void HttpRequestMapperByPath::service(HttpRequest &request,
                                      HttpResponse &response)
{
    QByteArray path = request.getPath();
    QString pathStr(path);
    qDebug() << "RequestMapper: path=" << pathStr;

    if(!m_responseMap.contains(QString(pathStr)))
    {
        //TODO: добавить отправку сообщения об ошибке
        return;
    }

    HttpRequestHandler* requestHandler = m_responseMap.value(pathStr);

    requestHandler->service(request, response);

    qDebug("RequestMapper: finished request");
}



Как видно из кода: есть базовый класс HttpRequestHandler, у него есть виртуальный метод service. Я его переопределил указанным выше способом. В этом методе я вытаскиваю из QHash указатель на объект класса HttpRequestHandler и в свою очередь вызываю его метод service. Так вот, указатель на объект HttpRequestMapperByPath я передаю в класс, который инициализирует определенное кол-во потоков и в них вызывает метод service класса HttpRequestMapperByPath. Собственно вопрос, не возникнет ли проблем с тем что на все потоки m_responseMap один? ну и не проглядел ли я еще возможные проблемы)
PM MAIL   Вверх
borisbn
Дата 21.3.2014, 13:34 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Если к моменту первого вызова HttpRequestMapperByPath::service хэш уже будет заполнен и изменяться больше точно не будет, то Qt гарантирует, что
Цитата
The container classes are implicitly shared, they are reentrant, and they are optimized for speed, low memory consumption, and minimal inline code expansion, resulting in smaller executables. In addition, they are thread-safe in situations where they are used as read-only containers by all threads used to access them.

А вот что делается в requestHandler->service(request, response); - трудно сказать...


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


Новичок



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

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



Спасибо большое) значит все будет нормально работать как я и предполагал. requestHandler->service(request, response); обязуется работать по тем же принципами, что и service его вызывающий. 
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
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.1084 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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