«новый» оператор в нескольких потоках вызывает ошибку сегментации - PullRequest
3 голосов
/ 26 августа 2010

Это связано с проблемой, которую я обсуждал здесь и здесь , но поскольку мои исследования привели меня к STL как потенциальной проблеме, и к "новой"В качестве своего врага я подумал, что лучше всего начать новую тему.

Повторюсь, я использую кросс-компилятор arm-linux (версия 2.95.2), поставляемый поставщиком встроенной платформы.

Когда я запускаю нижеприведенное приложение на моем ПК с Linux, оно, конечно, работает никогда.Однако при запуске его на встроенном устройстве каждый раз возникают ошибки сегментации.Использование «malloc» никогда не перестает.Синхронизация «нового» распределения с использованием мьютекса остановит проблему, но это не практично в моем основном приложении.

Может кто-нибудь подсказать, почему это может происходить, или есть идеи, как мне обойти эту проблему?

Спасибо.

#include <stdio.h>
#include <pthread.h>


pthread_mutex_t _logLock = PTHREAD_MUTEX_INITIALIZER;

static void* Thread(void *arg)
{
    int i = 0;
    while (i++ < 500)
    {
        // pthread_mutex_lock(&_logLock);
        char* myDyn = (char*) new char[1023];

        //        char* buffer = (char*) malloc(1023);
        //        if (buffer == NULL)
        //            printf("Out of mem\n");
        //        free(buffer);


        delete[] myDyn;

        //pthread_mutex_unlock(&_logLock);


    }
    pthread_exit(NULL);
}

int main(int argc, char** argv)
{
    int threads = 50;
    pthread_t _rx_thread[threads];
    for (int i = 0; i < threads; i++)
    {
        printf("Start Thread: %i\n", i);
        pthread_create(&_rx_thread[i], NULL, Thread, NULL);
    }

    for (int i = 0; i < threads; i++)
    {
        pthread_join(_rx_thread[i], NULL);
        printf("End Thread: %i\n", i);
    }
}

Ответы [ 4 ]

4 голосов
/ 26 августа 2010

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

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

2 голосов
/ 26 августа 2010

Как уже заявляли другие, есть вероятность, что поведение выделения памяти по умолчанию в наборе инструментов не является поточно-ориентированным.Я только что проверил 2 набора инструментов для кросс-разработки ARM, которые я использую чаще всего, и это действительно так с одним из них.

Большинство наборов инструментов предлагают способы сделать библиотеки поточно-ориентированными, либо путем повторной реализациифункции или путем ссылки в другой (потокобезопасной) версии библиотеки.Без дополнительной информации трудно сказать, чем занимается ваш конкретный набор инструментов.

Не хочется это говорить, но лучшая информация, вероятно, содержится в документации вашего набора инструментов.

1 голос
/ 26 августа 2010

Как насчет использования malloc (вы говорите, что на встроенной платформе никогда не происходит сбой), чтобы получить необходимую память, а затем с помощью размещения new (void * operator new [] (std :: size_t size, void * ptr) throw ()) в предположениидоступно, для строительства.См. new [] operator

Также см. Статью stackoverflow

и MSDN

1 голос
/ 26 августа 2010

Да, new, вероятно, не является потокобезопасным. Вам нужны механизмы синхронизации вокруг выделения памяти и, отдельно, вокруг удаления. Посмотрите на библиотеку Boost.thread , которая предоставляет типы мьютексов, которые должны вам помочь.

...