2016-03-15 4 views
1

Кажется, что это должно быть просто, но я не смог найти много связанных с ним. У меня есть структура, которая имеет разные поля, используемые для хранения данных о работе программы. Я хочу зарегистрировать эти данные, чтобы потом проанализировать их. Попытка постоянно регистрировать данные в ходе работы программы поглощает много ресурсов. Таким образом, я хотел бы просто вызвать функцию регистрации при изменении данных. Мне бы это понравилось, если бы был эффективный способ проверить, обновлены ли члены структуры. В настоящее время я играю в игру с тремя структурами (старыми, текущими и новыми), чтобы обнаружить, когда данные изменились. Заранее спасибо.Эффективный способ обнаружения изменений в элементах структуры?

+3

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

+0

с хорошим отладчиком, должно быть возможно установить точку наблюдения данных в вашу структуру, также должно быть возможно записать измененные данные в файл. – mfro

ответ

0

Вы можете отслеживать структуры и их хеши в своей функции регистрации.

Пусть у вас есть хэш-функции:

int hash(void* ptr, size_t size); 

Пусть у вас есть отображение указателя на структуру на структуру хеш, как:

/* Stores hash value for ptr*/ 
void ptr2hash_update_hash(void* ptr, int hash); 
/* Remove ptr from mapping */ 
void ptr2hash_remove(void* ptr); 
/* Returns 0 if ptr was not stored, or stored has otherwise*/ 
int ptr2hash_get_hash(void* ptr); 

Затем вы можете проверить, если ваш объект был изменен между лог называет так:

int new_hash = hash(ptr, sizeof(TheStruct)); 
int old_hash = ptr2hash_get_hash(ptr); 
if (old_hash == new_hash) 
    return; 

ptr2hash_update_hash(ptr, new_hash); 
/* Then do the logging */ 

не забудьте удалить ptr сюда m, когда вы делаете free(ptr) :)

Здесь simple hash table implementation, вам понадобится его для реализации отображения ptr2hash. Простые хэш-функции: here.

+0

Хеширование значения struct будет работать только в том случае, если вы можете гарантировать, что любое заполнение в структуре заполнено известными байтовыми значениями (обычно с нулевым заполнением). –

+0

Я не верю, что кто-то может изменить значение прокладки между вызовами ведения журнала – ivaigult

+0

Что делать, если структура содержит указатель на другие данные в качестве члена, а измененные данные меняются? Этот метод каким-то образом должен был стать рекурсивным. – SirDarius

0

Если вы работаете на Linux (x86 или x86_64), то другой возможный подход заключается в следующем:

Установить дескриптор сегмента для незаписываемого сегмента локальной таблицы дескрипторов, используя modify_ldt system call. Поместите свои данные внутри этого сегмента (или установите сегмент таким образом, чтобы ваша структура данных была в нем).

После доступа на запись ваш процесс получит SIGSEGV (ошибка сегментации). Установите обработчик, используя sigaction для обнаружения ошибок сегментации. Внутри этого обработчика сначала проверьте, что ошибка произошла внутри ранее заданного сегмента (si_addr member of the siginfo_t), и если да, подготовьте его для записи уведомления. Теперь измените дескриптор сегмента таким образом, чтобы сегмент стал доступен для записи и возвращался из обработчика сигнала.

Теперь запись будет выполнена, но вам нужен способ изменить сегмент, чтобы он был незаписанным и чтобы действительно проверить, что было написано, и если ваши данные действительно изменились.

Возможным подходом может быть передача себя (или «процесс задержки», а затем обратно в основной процесс) другой сигнал (например, SIGUSR1) и выполнение вышеуказанного в обработчике этого сигнала.

  • Является ли это переносным?
  • Является ли это reableable?
  • Легко ли это реализовать? No.

Так что, если вы можете, и я действительно надеюсь, что вы, используют интерфейс, как уже было предложено.

0

Самый простой способ, что вы можете попробовать, вы можете просто сохранить два structure pointers. После получения новых обновленных значений в это время вы можете просто сравнить new structure pointer с old structure pointer, и если есть какая-либо разница, вы можете его обнаружить, а затем можете обновить до old structure pointer, чтобы в дальнейшем вы могли обнаружить дальнейшие изменения обновленной стоимости.

typedef struct testStruct 
{ 
    int x; 
    float y; 
}TESTSTRUCT; 

TESTSTRUCT* getUpdatedValue() 
{ 
    TESTSTRUCT *ptr; 
    ptr->x = 5; 
    ptr->y = 6; 
    //You can put your code to update the value. 
    return ptr; 
} 

void updateTheChange(TESTSTRUCT* oldObj,TESTSTRUCT* newObj) 
{ 
    cout << "Change Detected\n"; 
    oldObj = newObj; 
} 

int main() 
{ 
    TESTSTRUCT *oldObj = NULL; 
    TESTSTRUCT *newObj = NULL; 

    newObj = getUpdatedValue(); 

    //each time a value is updated compae with the old structure 
    if(newObj == oldObj) 
    { 
     cout << "Same" << endl; 
    } 
    else 
    { 
     updateTheChange(oldObj,newObj); 
    } 

    return 0; 
} 

Я не уверен, это дает вам точный ответ или нет.

Надеюсь, что это поможет.

Смежные вопросы