Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 05.11.2013, 19:37   #1
Soeth
 
Регистрация: 30.06.2011
Сообщений: 7
По умолчанию Не понятная проблема, адрес переменной класса у 2 объектов класса одинаков

Добрый вечер, столкнулся с непонятной проблемой, хотелось бы попросить помощи у знающих людей. )

Есть класс:

Код:
class someClass {
  public:
    void function1() { std::cout << &var << std::endl; };

  private:
    int var;
};
Есть 2 потока, каждый создает свой объект типа someClass, а проблема заключается в том, что при вызове метода function1 что первый, что второй поток выдают один и тот же адрес переменной. Собственно в этом и проблема, 2 потока работают с одной переменной и одновременно меняют в ней данные.
Проблему можно решить синхронизацией потоков, к примеру мьютексами, но хотелось бы узнать у гуру, есть ли какая либо возможность 2 потокам одновременно работать с 2 объектами класса не блокируя первый пока работает второй ибо это не вариант если будет не 2, а 10 потоков работающих с этим объектом.
Спасибо за внимание.

Последний раз редактировалось Stilet; 05.11.2013 в 21:49.
Soeth вне форума Ответить с цитированием
Старый 05.11.2013, 19:41   #2
Rififi
Старожил
 
Регистрация: 19.08.2009
Сообщений: 2,120
По умолчанию

Soeth

каждый создает свой объект типа someClass
проблема заключается в том, что при вызове метода function1 что первый, что второй поток выдают один и тот же адрес переменной


не верю.
либо у тебя какой-то палёный и некачественный c++ сомнительного происхождения, скорее всего подделка из китая.
Rififi вне форума Ответить с цитированием
Старый 05.11.2013, 20:05   #3
Soeth
 
Регистрация: 30.06.2011
Сообщений: 7
По умолчанию

Цитата:
Сообщение от Rififi Посмотреть сообщение
Soeth

каждый создает свой объект типа someClass
проблема заключается в том, что при вызове метода function1 что первый, что второй поток выдают один и тот же адрес переменной


не верю.
либо у тебя какой-то палёный и некачественный c++ сомнительного происхождения, скорее всего подделка из китая.
Вот пример для проверки:
Код:
#include <iostream>
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <fstream>
#include <ctime>
#include <sys/timeb.h>
#include <string.h>

#define THREADS_COUNT 2

class someClass {
        public:
                void function1 () { std::cout << &var << std::endl; };
        private:
                int var;
};

int startedThreadCnt = 0;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

void *testThread( void *ptr ) {
        pthread_detach(pthread_self());
        pthread_mutex_lock(&mutex);
        startedThreadCnt++;
        pthread_mutex_unlock(&mutex);
        someClass myObj;
        myObj.function1();
}
void foo() {
        pthread_t thread[THREADS_COUNT];
        int threadStatus[THREADS_COUNT];
        startedThreadCnt = 0;
        for (int i = 0; i < THREADS_COUNT; i ++) {
                threadStatus[i] = pthread_create(&thread[i], NULL, testThread, NULL);
                if (threadStatus[i] != 0) {
                        std::cout << strerror(threadStatus[i]) << std::endl;
                }
        }
        while (startedThreadCnt < THREADS_COUNT) {
                usleep(250 * 1000);
        }
}

int main () {
        for (int i = 0; i < 3; i ++) {
                foo();
                std::cout << "Pack: " << i << std::endl;
        }
        return 0;
}
Что выдает:
0xb6c7837c
0xb747937c
Pack: 0
0xb747937c
0xb6c7837c
Pack: 1
0xb747937c
0xb6c7837c
Pack: 2

Компилятор g++, компилю: g++ threadTest.cpp -pthread -o threadTest

Как видно - адреса действительно повторяются..

Последний раз редактировалось Stilet; 05.11.2013 в 21:50.
Soeth вне форума Ответить с цитированием
Старый 05.11.2013, 21:41   #4
rrrFer
Санитар
Старожил
 
Аватар для rrrFer
 
Регистрация: 04.10.2008
Сообщений: 2,618
По умолчанию

странный пример, много лишнего, ИМХО.
зачем тут эти мьютексы, массивы статусов, счетчики запущенных потоков и прочее?

Если вдруг какой-то поток не удалось создать - ты навечно застрянешь в этом цикле:
Код:
while (startedThreadCnt < THREADS_COUNT) {
                usleep(250 * 1000);
        }
разве нет?

Цитата:
Что выдает:
0xb6c7837c
0xb747937c
Pack: 0

Компилятор g++, компилю: g++ threadTest.cpp -pthread -o threadTest

Как видно - адреса действительно повторяются..
В каком месте они повторяются? - у тебя в каждом потоке своя переменная со своим адресом, смотри внимательно

Последний раз редактировалось rrrFer; 05.11.2013 в 21:51.
rrrFer вне форума Ответить с цитированием
Старый 05.11.2013, 23:29   #5
Rififi
Старожил
 
Регистрация: 19.08.2009
Сообщений: 2,120
По умолчанию

0xb6c7837c
0xb747937c

раз, два, три, дальше много... :lol:
Rififi вне форума Ответить с цитированием
Старый 06.11.2013, 01:42   #6
Soeth
 
Регистрация: 30.06.2011
Сообщений: 7
По умолчанию

Цитата:
Сообщение от rrrFer Посмотреть сообщение
странный пример, много лишнего, ИМХО.
зачем тут эти мьютексы, массивы статусов, счетчики запущенных потоков и прочее?

Если вдруг какой-то поток не удалось создать - ты навечно застрянешь в этом цикле:
Код:
while (startedThreadCnt < THREADS_COUNT) {
                usleep(250 * 1000);
        }
разве нет?



В каком месте они повторяются? - у тебя в каждом потоке своя переменная со своим адресом, смотри внимательно
Мьютекс для того, что бы 2 потока вдруг одновременно 1 переменную не увеличили.
Счетчики запущеных потоков для того, что по постановке задачи я должен запустить функцию, которая запустит несколько потоков и не дожидаясь их завершения отработает и завершится и будет вызвана снова для запуска уже новой пачки потоков, только уже с другими параметрами. Если не дождаться запуска всех потоков и сделать выход из ф-ии, которая запускает потоки, то не факт, что все потоки успеют запустится и будут удалены локальные переменные, которые передаются потоковой ф-ии в качестве параметра. В примере простоты ради этого нет.
А проблема собственно в том, что адрес var в этих 3 пачках одинаков и если первая пачка потоков еще будет работать с объектом класса someClass в тот момент, когда будет запущена вторая пачка потоков, то произойдет обращение 2 потоков к одному участку памяти.
0xb6c7837c
0xb747937c
Pack: 0
0xb747937c
0xb6c7837c
Pack: 1
0xb747937c
0xb6c7837c
Pack: 2
В данном примере потоки отрабатывают быстро, и успевают завершится за 250 миллисекунд (usleep(250 * 1000), но в случае, если someClass производит, к примеру, скачивание и потом обработку данных, которая занимает секунд 5-10, а интервал между запусками пачек потоков 1-2 секунды будет акая проблема.
Soeth вне форума Ответить с цитированием
Старый 06.11.2013, 04:44   #7
rrrFer
Санитар
Старожил
 
Аватар для rrrFer
 
Регистрация: 04.10.2008
Сообщений: 2,618
По умолчанию

Цитата:
Мьютекс для того, что бы 2 потока вдруг одновременно 1 переменную не увеличили.
Счетчики запущеных потоков для того, что по постановке задачи я должен запустить функцию, которая запустит несколько потоков и не дожидаясь их завершения отработает и завершится и будет вызвана снова для запуска уже новой пачки потоков, только уже с другими параметрами. Если не дождаться запуска всех потоков и сделать выход из ф-ии, которая запускает потоки, то не факт, что все потоки успеют запустится и будут удалены локальные переменные, которые передаются потоковой ф-ии в качестве параметра. В примере простоты ради этого нет.
Я к тому, что в примере много всего лишнего, не относящегося к вопросу есть.
rrrFer вне форума Ответить с цитированием
Старый 06.11.2013, 04:48   #8
rrrFer
Санитар
Старожил
 
Аватар для rrrFer
 
Регистрация: 04.10.2008
Сообщений: 2,618
По умолчанию

Цитата:
В данном примере потоки отрабатывают быстро, и успевают завершится за 250 миллисекунд (usleep(250 * 1000), но в случае, если someClass производит, к примеру, скачивание и потом обработку данных, которая занимает секунд 5-10, а интервал между запусками пачек потоков 1-2 секунды будет акая проблема
проблемы не будет. Хватит нам голову морочить, предсказатель. Когда будет - тогда и пиши.
Потоки завершаются, создаются новые, такие же. Почему адреса должны быть другими?

Впихни внутрь свой тестовой функции вечный цикл, чтобы поток не завершился и смотри на разные адреса.

Не придумывай проблем, их и так хватает )

Не поленился, впихнул, проверил, работает:
Изображения
Тип файла: png test.png (5.9 Кб, 49 просмотров)

Последний раз редактировалось rrrFer; 06.11.2013 в 04:50.
rrrFer вне форума Ответить с цитированием
Старый 06.11.2013, 05:10   #9
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,000
По умолчанию

Цитата:
А проблема собственно в том, что адрес var в этих 3 пачках одинаков и если первая пачка потоков еще будет работать с объектом класса someClass в тот момент, когда будет запущена вторая пачка потоков, то произойдет обращение 2 потоков к одному участку памяти.
да не будет. у вас полностью независимые пачки, потому между ними он и может повториться.
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Проблема с массивом экземпляров класса переменной длины Xuch Общие вопросы C/C++ 5 26.03.2013 13:00
Для public переменной класса присвоить адрес ячеек из внешней переменной _KUL Qt и кроссплатформенное программирование С/С++ 2 28.05.2012 12:04
Конструктор класса не хочет принимать в качестве параметра адрес объекта другого класса Jugger Помощь студентам 3 05.01.2012 04:10
Определение типа класса по переменной на объект этого класса при компиляции phomm Общие вопросы Delphi 24 08.04.2011 14:11
Адрес метода класса? VintProg Общие вопросы Delphi 6 27.09.2009 13:10