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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Адрес члена класса у 2 объектов класса 
:(
    Опции темы
Soeth
Дата 5.11.2013, 18:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



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

Есть класс:

Код

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

  private:
    int var;
};

Есть 2 потока, каждый создает свой объект типа someClass, а проблема заключается в том, что при вызове метода function1 что первый, что второй поток выдают один и тот же адрес переменной. Собственно в этом и проблема, 2 потока работают с одной переменной и одновременно меняют в ней данные.
Проблему можно решить синхронизацией потоков, к примеру мьютексами, но хотелось бы узнать у гуру, есть ли какая либо возможность 2 потокам одновременно работать с 2 объектами класса не блокируя первый пока работает второй ибо это не вариант если будет не 2, а 10 потоков работающих с этим объектом.
Спасибо за внимание.
PM MAIL   Вверх
Cheloveck
Дата 6.11.2013, 00:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1578
Регистрация: 26.7.2008
Где: Тула

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



Код

#include <iostream>
#include <pthread.h>

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

void * test(void * ptr)
{
    someClass c;
    c.function1();
    pthread_exit(0); 
}

int main()
{
    pthread_t thread1, thread2;
    pthread_create(&thread1, NULL, test, NULL);
    pthread_create(&thread2, NULL, test, NULL);
    pthread_join(thread1, NULL);
    pthread_join(thread2, NULL);
}


Код

$ g++ test.cpp -lpthread
$ ./a.out 
0x7faf5bc81e90
0x7faf5b480e90


Цитата(Soeth @  5.11.2013,  19:47 Найти цитируемый пост)
что первый, что второй поток выдают один и тот же адрес переменной

 smile 


Это сообщение отредактировал(а) Cheloveck - 6.11.2013, 00:35


--------------------
user posted image
PM Jabber   Вверх
Soeth
Дата 6.11.2013, 02:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата(Cheloveck @ 6.11.2013,  00:34)
Код

#include <iostream>
#include <pthread.h>

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

void * test(void * ptr)
{
    someClass c;
    c.function1();
    pthread_exit(0); 
}

int main()
{
    pthread_t thread1, thread2;
    pthread_create(&thread1, NULL, test, NULL);
    pthread_create(&thread2, NULL, test, NULL);
    pthread_join(thread1, NULL);
    pthread_join(thread2, NULL);
}


Код

$ g++ test.cpp -lpthread
$ ./a.out 
0x7faf5bc81e90
0x7faf5b480e90


Цитата(Soeth @  5.11.2013,  19:47 Найти цитируемый пост)
что первый, что второй поток выдают один и тот же адрес переменной

 smile

Немного не правильно сформулировал проблему.
Если запускать 2 потока или один, которые используют объект класса someClass, и не дожидаясь завершения потоков (без pthread_join()) снова создавать потоки использующие данный класс, то тогда адрес var первого работающего потока будет такойже как адрес var второго потока.
Пример:
Код

#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

Пока первая пачка потоков успевает отработать до запуска второй пачки потоков всё в порядке, но если к потоки будут работать к примеру по 5-10 секунд, а интервал между вызовами foo() будет 1-2 секунды, то получится, что все потоки будут работать с одним и тем же участком памяти.

Хотелось бы решить данную задачу без применения мьютексов и блокировки var на время работы одной пачки потоков т.к. в реальной задаче необходимо запускать эти "пачки" потоков в сравнительно небольшом интервале времени относительно времени выполнения потоковой ф-ии. Т.е. очередь потоков, ожидающих доступа к var будет только расти.
PM MAIL   Вверх
feodorv
Дата 6.11.2013, 20:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Простите, но новые потоки просто занимают то же адресное пространство, что и завершившиеся старые, соответственно, адреса и совпадают. Это отнюдь не значит, что старые (от предыдущей пачки) потоки всё ещё работают, а новые (от новой пачки) внезапно начали работать с перекрывающимися областями памяти. Не нужна Вам здесь синхронизация.

Код

#include <stdio.h>
#include <stdlib.h>

int main( void )
{
  char *p;

  p = malloc( 10 );
  printf( "p1 = %p\n", p);
  free( p );

  p = malloc( 10 );
  printf( "p2 = %p\n", p);
  free( p );

  return 0;
}


Цитата

p1 = 00410350
p2 = 00410350



--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С/С++: Программирование под Unix/Linux"
xvr
  • Проставьте несколько ключевых слов темы, чтобы её можно было легче найти.
  • Не забывайте пользоваться кнопкой "Код".
  • Вопросы мобильной разработки тут
  • Телепатов на форуме нет! Задавайте чёткий, конкретный и полный вопрос. Указывайте полностью ошибки компилятора и компоновщика.
  • Новое сообщение должно иметь прямое отношение к разделу форума. Флуд, флейм, оффтопик запрещены.
  • Категорически запрещается обсуждение вареза, "кряков", взлома программ и т.д.

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

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


 




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


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

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