手动锁定:list_sorted_insert位于列表末尾与中间位置

时间:2016-05-12 15:59:00

标签: c multithreading linked-list locking

手动锁定也称为锁定耦合或细粒度锁定。它是每个节点锁定的地方,而不是仅用一个锁定来锁定整个列表。

无论如何,我写了一个线程安全的链表,我想证明我已经锁定了最少量的锁,以避免死锁和数据损坏......除了给出步骤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;

0 个答案:

没有答案