【发布时间】:2016-02-17 05:26:46
【问题描述】:
我有一个程序可以让多个线程将条目插入哈希表并检索它们。哈希表本身是一个非常简单的实现,它有一个定义每个桶条目的结构和一个保存每个桶的表(数组)。我对并发和多线程非常陌生,但我认为为了避免在插入和读取操作期间数据在表中丢失,需要添加某种同步(以互斥锁之类的形式)以避免一个进程的数据操作被另一个进程抢占。
但在实践中,我不确定如何判断在哈希表上的数据读取或写入操作中进程可以在何处被抢占,以及应该在何处放置锁以避免此类问题以及死锁。根据this 网站,对于哈希表插入方法,我在将每个键插入表之前添加了一个互斥锁,并在函数结束时将其解锁。我基本上在从哈希表读取数据的函数中做了类似的事情,当我运行代码时,最初似乎成功插入了密钥,但是当应该检索密钥时程序挂起。以下是我为每个函数实现锁定的方法:
// 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()找到匹配的键,则返回对象而不释放锁。如果它没有找到密钥,它将退出线程。奇怪。 -
您的程序挂起,因为您在返回成功命中时没有解锁互斥锁。但是为什么你在这两个函数中都执行 pthread_exit 呢?这没有任何意义。
标签: c linux multithreading operating-system pthreads