[c++] Проблема с алокацией данных памяти в многопоточномприложении

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by razzzar, 17 Mar 2008.

  1. razzzar

    razzzar Elder - Старейшина

    Joined:
    16 Jun 2007
    Messages:
    92
    Likes Received:
    75
    Reputations:
    5
    Есть программа, в которой вызывается большое количество потоков ( около 1000 ). Каждый поток должен обработать данную ему строку. В потоке создается экземпляр класса и вызывается функция данного класса. В этой функции создается экземпляр класа std::string и присвоение ему данных методом assign(). ,Вот пр этом присвоении программа вылетает с ошибкой с брейк-поинтом в malloc.c в релизе и в xstring в дебаге.
    Интересен тот факт, что при малом количестве потоков ( напрмиер, 5 ) никаких ошибок не происходит и все нормально работает.
    Помогите решить проблему, а то уже запарился :confused:
     
    1 person likes this.
  2. spider-intruder

    spider-intruder Elder - Старейшина

    Joined:
    9 Dec 2005
    Messages:
    700
    Likes Received:
    339
    Reputations:
    37
    Если на сях дай пример рабочий - чет с памятью может
     
  3. wda

    wda New Member

    Joined:
    14 Feb 2008
    Messages:
    21
    Likes Received:
    3
    Reputations:
    0
    Посмотри код этот: _http://zbrute.antichat.ru/zbrute.c

    Тебе интересен текст содержащий "CriticalSection". Мануала много в сети по этому объекту и не только.

    Суть такова: сначала инициализируешь CriticalSection, потом как только нужно доступиться до данных в монопольном режиме захватываешь секцию, делаешь свои дела, отпускаешь секцию, в конце проги дестроишь ее.
     
  4. razzzar

    razzzar Elder - Старейшина

    Joined:
    16 Jun 2007
    Messages:
    92
    Likes Received:
    75
    Reputations:
    5
    wda,
    читай внимательно. про синхронизацию я нислова не сказал. я спрашиваю именно о аллокации памяти.
    вот некоторая часть кода:
    Code:
    // создаем поток и передаем ему его номер
    hThreads = new HANDLE [nThreads];
    for ( int i=0; i<nThreads; i++ )
    {
    		hThreads[i] = CreateThread(0, 0, Thread, (LPVOID) i, 0, 0);
    }
    
    // ...
    
    unsigned long __stdcall Thread(LPVOID lpParam)
    {
    int nId = (int) lpParam;
    Class clC;
    clC.func1("qwe");
    return 1;
    }
    
    // ...
    
    int Class::func1(const char * szString)
    {
    std::string strString;
    strString.assing(szString);
    // обработка строки
    // ...
    }
    
    я попробовал создать маленькую прогу, которая создает 3к потоков и в каждом из них создает string и делает assing(). все работает на ура. но как только я в потоке создаю экземпляр класса и вызываю его метод, де создается string и делается assing - все сразу вылетает (((
     
    #4 razzzar, 17 Mar 2008
    Last edited: 17 Mar 2008
  5. wda

    wda New Member

    Joined:
    14 Feb 2008
    Messages:
    21
    Likes Received:
    3
    Reputations:
    0
    Верно ли я понял, что под аллокацией ты понимашь распределение между потоками некоторого ресурса, т.е. каждый поток берет для обработки некую часть ресурса и эту часть не берет ни один из других потоков?
     
  6. razzzar

    razzzar Elder - Старейшина

    Joined:
    16 Jun 2007
    Messages:
    92
    Likes Received:
    75
    Reputations:
    5
    wda, не верно. аллокация - выделение памяти.
     
  7. wda

    wda New Member

    Joined:
    14 Feb 2008
    Messages:
    21
    Likes Received:
    3
    Reputations:
    0
    Пардон, это я понимание аллокации из экономики ассоциирую.
    Ну да ладно. Смотри, я вообще на Делфях пишу, но думаю на сях таже беда. Когда много процессов работают со строками, стримами, массивами и т.д. или несколько но с большим куском памяти, используют следующие методы: malloc, realloc для віделения памяти и в конце free для освобождения. Мож поможет тебе, хотя я думаю ты это уже перепробовал. =)
     
    #7 wda, 17 Mar 2008
    Last edited: 17 Mar 2008
  8. Xserg

    Xserg Elder - Старейшина

    Joined:
    9 Dec 2006
    Messages:
    135
    Likes Received:
    127
    Reputations:
    53
    Запустил 5000 потоков
    Code:
     unsigned long __stdcall Thread(LPVOID * lpParam)
    {
    int nId = (int) lpParam;
    Class clC;
    clC.func1("qwerty",lpParam);
    return 1;
    }
    
    int Class::func1(const char * szString, const HANDLE nThread)
    {
    std::string strString;
    strString.assign(szString);
    if (strString=="qwerty") { printf("%d ok \n",nThread);}
    return (strString._BUF_SIZE);
    } 
    0 ok


    4999 ok

    Может с
    ,что не так ?
     
  9. ZaCo

    ZaCo Banned

    Joined:
    20 Jun 2005
    Messages:
    737
    Likes Received:
    336
    Reputations:
    215
    не буду говорить точно, но вроде бы new и malloc являются thread-safe, то есть проблем с какими-то внутренними разделяемыми между потоками переменными быть не должно.. в любом случае попробуй сделать код объявления объектов строки заключенным в критическую секцию.. вполне возможно что-то внутри реализации класса srting не то, бог знает твой компилятор с stl'ом. в общем тестируй не на таких объектах, на чем-нибудь попроще..
     
  10. Delimiter

    Delimiter Banned

    Joined:
    8 Apr 2005
    Messages:
    317
    Likes Received:
    173
    Reputations:
    12
    да переменные у него и так внутренние никаких критических секций тут не нужно...

    .... хммм тож попробывал и все намана.

    и ваапще не нужно использовать элементы которые ты
    не контролируешь.... (это же Си.... верить чужим классам не проверяя параметры MAX_SIZE... НЕЛЬЗЯ)
    Иначе начнем рождать "чудеса" у одного пашет у другого нет.... как будто программирование это факирство какоето... :p


    все же просто...

    char *str;
    str=new char[MAX_SIZE];

    отрабатывать....

    delete[] str;

    либо используй malloc , но в обоих случаях ты контролируешь процесс создания программы, а если ты сделал код который вылетает на другом компиляторе , то вспомнишь ли ты о макисмальных разерах буферов, которые могут быть отличными от твоих!
     
    #10 Delimiter, 18 Mar 2008
    Last edited: 18 Mar 2008
    1 person likes this.
  11. razzzar

    razzzar Elder - Старейшина

    Joined:
    16 Jun 2007
    Messages:
    92
    Likes Received:
    75
    Reputations:
    5
    Delimiter,
    да класс напсиан мною. в нем я вызываю функцию в новом потоке, которая вызывает приватный метод класса. в этом методе создается string... и вылетает. замечено что вылетает через раз =\ видимо де-то или утечка памяти или еще что-то. даже когда в методе ниче не делаю кроме как char *str = new char[MAX_SIZE]; lstrcpy(str, s_; delete [] str; тоже вылетает (((

    update

    хм... мистика какая-то )
    запускаю программу из-под студии - вылетает,
    запускаю программу вне всяких отладчиков - работает...
     
    #11 razzzar, 18 Mar 2008
    Last edited: 18 Mar 2008