Разделяемая память и ее защита.
От: Ivych  
Дата: 04.12.18 19:31
Оценка:
Добрый вечер, форумчане!

Имеется вопрос, есть в проекте (операционка QNX4.25) несколько разделяемых объектов памяти, для взаимодействия между процессами. Есть один писатель в каждую из них и несколько читателей, я написал несколько функций оберток вида:

void XXXX_ShmemLock()
{
    assert( g_Shmem );
    sem_wait( &g_Shmem->lock );
}

void XXXX_ShmemUnlock()
{
    assert( g_Shmem );
    sem_post( &g_Shmem->lock );
}

void XXXX_ShmemCopy( void *destination, const void *source, const size_t num )
{
    XXXX_ShmemLock();
    _disable();
    memcpy( destination, source, num );
    _enable();
    XXXX_ShmemUnlock();
}


Дальнейшие операции более высокого уровня, выполняются путем вызова функций-оберток, как пример приложу:
void XXXX_ReadADC( const ADCChannel_t channel, double *voltage )
{
    assert( channel < ADC_ChannelsNum );
//    *voltage = g_Shmem->Vin[channel];
    XXXX_ShmemCopy( (void *)voltage, (const void *)&g_Shmem->Vin[channel], sizeof(g_Shmem->Vin[channel]) );
}

void XXXX_WriteADC( const ADCChannel_t channel, const double voltage )
{
    assert( channel < ADC_ChannelsNum );
//    g_Shmem->Vin[channel] = voltage;
    XXXX_ShmemCopy( (void *)&g_Shmem->Vin[channel], (const void *)&voltage, sizeof(voltage) );
}

P.S. Насколько рационален такой подход?

Так вот, как видно в функции XXXX_ShmemCopy, копирование данных в область и из нее, производится вызовом memcpy, обернутым в семафор и дополнительным отключением прерываний на момент копирования, чтобы обеспечить атомарность операции. Есть ли вообще смысл в такой перестраховке на однопроцессорной системе? Минус в использовании _disable()/_enable() при больших объемах копирования (которых скорее всего не будет), на момент выполнения операции, стопорится работа всей системы, или если вызовов XXXX_ShmemCopy будет много (а их скорее всего будет много), то рискуем то и делать что бесконечно выключать/включать прерывания. Так же есть ли необходимость оборачивания простых операций вида "Область->переменная = что-то записать", понятное дело не делая справа от "=" сложных операций, будет ли такая операция выполнена атомарно?
qnx unix posix semaphore shared
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.