Перейти к содержанию
    

new и scmRTOS

Делаю проект с использованием оси и с динамическим созданием объектов.

Причем, создание и удаление объектов производяться в различных по приоритету (разумеется) процессах. Программа работает несколько минут, потом виснет (включая айдл процесс, тикает только системник). Наибольший адрес объекта, созданного когда-либо в рантайме, вылетает далеко за пределы кучи. Все сводится к тому, что проблема в создании обекта в одном из процессов. Так вот вопрос, можно ли безопасно создавать объекты в разных процессах, не опасаясь, что процедура "new" будет прервана высшестоящим процессом, в котором тоже запустится new, c вытекающим сбоем в работе динамической памяти??

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

можно ли безопасно создавать объекты в разных процессах, не опасаясь, что процедура "new" будет прервана высшестоящим процессом,
Нет, нельзя. Переопределите глобальные operator new() и operator delete() - обрамите в нем malloc() и free() глобальным TMutex.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Нет, нельзя. Переопределите глобальные operator new() и operator delete() - обрамите в нем malloc() и free() глобальным TMutex.

Опс, а как там выделить эти malloc и free? Если не сложно, можно небольшой примерчик?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Если не сложно, можно небольшой примерчик?
Примерно так:
#include    <stdint.h>
#include    <new>
#include    <scmRTOS.h>
extern bool FreeMemory();  // Ищет память: сборка мусора. возвращает false если памяти не нашлось

class heap_mutex_t
{
public:
    heap_mutex_t() { Mutex.Lock(); }
    ~heap_mutex_t() { Mutex.Unlock(); }
private:
    static OS::TMutex Mutex;
};

OS::TMutex heap_mutex_t::Mutex;

void * operator new(size_t size)
{
    for(;;)
    {
        void * Tmp;
        {
            heap_mutex_t Lock;
            Tmp = malloc(size);
        }
        if(Tmp)
            return Tmp;
        else
            // пытаемся найти память
            if(! FreeMemory() )
                return 0;
    }
}

void * operator new (size_t size, const _STD nothrow_t& )
{
    return operator new(size);
}

void operator delete( void * pobject )
{
    heap_mutex_t Lock;
    free(pobject);
}

"настоящий" new не возвращает 0. Мне было удобнее так. Поправьте, как вам удобнее.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

#include    <stdint.h>
#include    <new>
#include    <scmRTOS.h>

void * operator new(size_t size)
{
    for(;;)
    {
        void * Tmp;
        {
            heap_mutex_t Lock;
            Tmp = malloc(size);
        }
        if(Tmp)
            return Tmp;
        else
            // пытаемся найти память
            if(! FreeMemory() )
                return 0;
    }
}


void operator delete( void * pobject )
{
    heap_mutex_t Lock;
    free(pobject);
}

А где же в этих "новых" new и delete вызовы конструктора и деструктора объекта?!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А где же в этих "новых" new и delete вызовы конструктора и деструктора объекта?!

Конструктор вызывается при создании обьекта Lock, а деструктор - при уничтожении этого обьекта, когда он покидает область видимости, в первом случае это блок, во втором - вся функция.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Конструктор вызывается при создании обьекта Lock, а деструктор - при уничтожении этого обьекта, когда он покидает область видимости, в первом случае это блок, во втором - вся функция.

Нет-нет, я про тот объект, который создается собственно оператором new. Ведь new и malloc- это не совсем идентичные функции,- new выделяет память под объект заданного типа и запускает конструктор этого объекта- и вот, память выделили, а конструктор?! Чего то недопонимаю? :wacko:

extern bool FreeMemory(); // Ищет память: сборка мусора.

А сборка мусора -это , по-сути, дефрагментация кучи, что б дырок не было?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Нет-нет, я про тот объект, который создается собственно оператором new.
А запуск конструктора вставляется компилятором после вызова operator new() после проверки результата на ноль. Такие вопросы очень легко разрешаются чтением листинга.

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спасибо за обстоятельные ответы. Заработало :-) Может, включить эти измененные new и delete в дистрибутив оси?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

...Может, включить эти измененные new и delete в дистрибутив оси?

В некоторых случаях функции malloc() и free() пользователи сами переписывают под свои нужды. Универсального решения не получится. Не думаю, что стоит включать частное решение в дистрибутив, разве что только как пример конкретного решения в примерах.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...