手动锁定也称为锁定耦合或细粒度锁定。它是每个节点锁定的地方,而不是仅用一个锁定来锁定整个列表。
无论如何,我写了一个线程安全的链表,我想证明我已经锁定了最少量的锁,以避免死锁和数据损坏......除了给出步骤I采取锁定和解锁。
我没有问题为list_pop,list_push_end和list_sorted_insert(插入中间)提供理由。不幸的是,我实现我的listing_sorted_insert(在最后插入)的方式几乎与在中间插入相同。我最初说他们是一样的,直到我读到我这样做不正确。
To avoid both deadlock and corrupted data...
Accomplishing both of these is significantly different for inserting
at the end vs. in the middle.
如何在列表末尾插入“显着不同”而不是插入中间?我在下面的代码中哪里出错了?除了if语句之外,我仍然不相信它们是相同的。
void list_sorted_insert(list_t *list, int value)
{
list_item_t *item;
assert(list != NULL);
list_item_t *new_item = NEW_ITEM(new_item);
new_item->value = value;
LOCK_LIST(list);
LOCK_ITEM(list);
if (list->first == NULL || value < list->first->value)
{
// special case inserting at beginning of list
new_item->next = list->first;
list->first = new_item;
if (list->last == NULL) list->last = new_item;
list->count++;
UNLOCK_ITEM(list);
}
else
{
item = list->first;
LOCK_ITEM(item);
UNLOCK_ITEM(list);
while (item->next != NULL && item->next->value < value)
{
#ifdef HOH_LOCKING
list_item_t * pItem = item;
#endif
LOCK_ITEM(item->next);
item = item->next;
UNLOCK_ITEM(pItem);
}
//sched_yield();
new_item->next = item->next;
item->next = new_item;
UNLOCK_ITEM(item);
LOCK_ITEM(list);
if (item->next == NULL) {
list->last = new_item;
}
list->count++;
UNLOCK_ITEM(list);
}
UNLOCK_LIST(list);
}
我看到的唯一问题是在解锁项目然后锁定列表之间(这些语句和do_bad_stuff之间是否有线程?),但这与插入中间与插入之间的区别无关结束。
有没有人知道我的代码中缺少什么,以及为什么在最后插入需要显着不同以避免死锁和损坏的数据?
编辑:更相关的代码
#define LOCK_MUTEX(mutex) assert(pthread_mutex_lock(&(mutex)) == 0)
#define UNLOCK_MUTEX(mutex) assert(pthread_mutex_unlock(&(mutex)) == 0)
#define LOCK(hasMutexPtr) LOCK_MUTEX((hasMutexPtr)->mutex)
#define UNLOCK(hasMutexPtr) UNLOCK_MUTEX((hasMutexPtr)->mutex)
#ifdef HOH_LOCKING
#define LOCK_LIST(listPtr)
#define UNLOCK_LIST(listPtr)
#define LOCK_ITEM(item) LOCK(item)
#define UNLOCK_ITEM(item) UNLOCK(item)
#define NEW_ITEM(item) (list_item_t *)malloc(sizeof(list_item_t)); \
assert(item != NULL); \
pthread_mutex_init(&(item->mutex), NULL)
#else
#define LOCK_LIST(listPtr) LOCK((listPtr))
#define UNLOCK_LIST(listPtr) UNLOCK((listPtr))
#define LOCK_ITEM(item)
#define UNLOCK_ITEM(item)
#define NEW_ITEM(item) (list_item_t *)malloc(sizeof(list_item_t)); \
assert(item != NULL)
#endif
// Struct for elements in a singly linked list
typedef struct list_item_s
{
int value; // value stored in list element
struct list_item_s *next; // pointer to next list element
#ifdef HOH_LOCKING
pthread_mutex_t mutex;
#endif
} list_item_t;
//*******************************************************
// struct for a list made up of list_item_t elements
typedef struct list_s
{
int count; // number of items in the list
struct list_item_s *first; // pointer to first element in list
struct list_item_s *last; // pointer to last element in list
pthread_mutex_t mutex;
} list_t;