2012-02-02 1 views
1

Этот вопрос является возможным суб проблема с этим concurrent access and free of a data structureодновременный доступ и без кучи объекта

Другой вопрос открыт для проектирования, это один более конкретно.

struct ds 
{ 
    int x,y,z;  
    pthread_mutex_t mutex; 
}; 

мне нужно детерминированное решение с помощью которого можно одновременно получать доступ к 1 объект типа DS и освободить ее.

Сдерживает:

  1. Вы можете сделать мьютекс указатель, но не может взять его из объекта.

Реальная проблема:

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

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

+0

Я предполагаю, что проблема сводится к тому, что во время свободного времени нет внешних ссылок на объект. Поэтому, если внешние ссылки являются указателями, нам понадобится еще одна блокировка вне ds, чтобы гарантировать, что объект не исчез. Вот почему они изобрели shared_ptr в boost. – Saurabh

ответ

1

Так вы говорите, что «мьютекс может быть указателем», вы могли бы сделать что-то вроде этого:

struct ds { pthread_mutex_t * mutex; /* ... */ }; 

struct ds * create_ds() 
{ 
    struct ds * p = calloc(1, sizeof(struct ds)); 
    pthread_mutex_t * q = malloc(sizeof(pthread_mutex_t)); 
    pthread_mutex_init(q, NULL); 
    ds->mutex = q; 
    return p; 
} 

void free_ds(struct ds * p) 
{ 
    pthread_mutex_t * q = p->mutex; 
    pthread_mutex_lock(q); 
    free(p); 
    pthread_mutex_unlock(q); 
    pthread_mutex_destroy(q); 
    free(q); 
} 

На мой взгляд, хотя, уничтожая объект на самом деле не то, что соответствует параллельный доступ/синхронизация идиомы. Если вы что-то уничтожите, его больше нет, поэтому все потоки затронуты этим. Как поток должен знать, указывает ли данный указатель ds на что-то действительное?

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

+0

Код в 'free_ds' по-прежнему небезопасен: что делать, если уничтожение мьютекса выполняется, когда другой поток, который имеет адрес того же экземпляра' struct ds', пытается получить к нему доступ? –

+0

@ AlexeyKukanov: Как я уже сказал в последних двух параграфах, я не думаю, что вы можете использовать элемент-мьютекс для защиты от мутации * container *, и поэтому освобождение элемента действительно должно быть защищено кем-то другим, а не элементом сам. –

+0

@KerrekSB Я придерживаюсь того же мнения, что эта проблема неразрешима, независимо от того, находится ли мьютекс или его указатель внутри структуры данных. Я думаю, что может быть какое-то решение, используя атомную инструкцию CAS/указатель опасности, как это было предложено кем-то из исходной проблемы. – Saurabh

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