У меня есть программа, которая позволяет нескольким потокам вставлять записи в хэш-таблицу и извлекать их. Хэш-таблица сама по себе является очень простой реализацией со структурой, определяющей каждую запись в виде ведра, и таблицу (массив) для хранения каждого ведра. Я очень к новому для параллелизма и многопоточности, но я думаю, что для того, чтобы избежать потери данных в таблице во время операций вставки и чтения, необходимо добавить некоторую синхронизацию (в виде чего-то вроде блокировки мьютекса) чтобы избежать превенции в работе данных одного процесса другими.Как определить, где данные теряются при использовании многопоточности
На практике, однако, я не совсем уверен, как определить, где процесс может быть вытеснен либо в операции чтения или записи данных на хэш-таблице, и там, где должны быть установлены блокировки, чтобы избежать таких проблем, как и мертвые блокировки , По адресу this веб-сайт, для метода insert hashtable, я добавил блокировку мьютекса, прежде чем каждый ключ встанет в таблицу и разблокирует ее в конце функции. Я по сути делаю что-то подобное в функции, где я читаю данные из хэш-таблицы, и когда я запускаю код, кажется, что ключи успешно вставлены изначально, но программа зависает, когда ключи должны быть извлечены. Вот как я осуществил блокировку для каждой функции:
// Inserts a key-value pair into the table
void insert(int key, int val) {
pthread_mutex_lock(&lock);
int i = key % NUM_BUCKETS;
bucket_entry *e = (bucket_entry *) malloc(sizeof(bucket_entry));
if (!e) panic("No memory to allocate bucket!");
e->next = table[i];
e->key = key;
e->val = val;
table[i] = e;
pthread_mutex_unlock(&lock);
pthread_exit(NULL);
}
// Retrieves an entry from the hash table by key
// Returns NULL if the key isn't found in the table
bucket_entry * retrieve(int key) {
pthread_mutex_lock(&lock);
bucket_entry *b;
for (b = table[key % NUM_BUCKETS]; b != NULL; b = b->next) {
if (b->key == key) return b;
}
pthread_mutex_unlock(&lock);
pthread_exit(NULL);
return NULL;
}
Так основные проблемы здесь:
Как сказать, где данные теряются между каждой операцией резьбы
Что может ли программа зависать, когда ключи извлекаются из хеш-таблицы?
Вы * не можете * указать, когда будет использоваться поток, поэтому вы используете блокировки для защиты общих ресурсов. Кстати, функция 'insert' состоит в том, что вся функция потока? Это все протекторы? Это не очень полезно для потока. –
Если 'retrieve()' находит соответствующий ключ, он возвращает объект, не отпуская блокировку. Если он не находит ключ, он выходит из потока. Bizarre. – keithmo
Ваша программа зависает, потому что вы не открываете мьютекс, когда вы возвращаете успешный хит.Но почему вы выполняете pthread_exit в обеих функциях? Это не имеет никакого смысла. – Art