C 中细粒度的线程安全链表

threads safe linked list fine grained in C

我正在实现一个具有细粒度锁定的链表,这意味着每个节点都有一个锁。

当我添加一个新节点时,我只想传递 2 个参数:键和值。 如何确保每个节点都有不同的锁?锁由pthread_mutex_t.

实现

这是我要添加的实现:

int setos_add(int key, void* value)
{
volatile setos_node* node = head;
volatile setos_node* prev;

pthread_mutex_t new_mutex;  //wrong: it will put the same lock to everyone

//lock the head node
if(pthread_mutex_lock(&(node->mutex)) == 0){
    printf("failed locking\n");
    exit(1);
}

// go through nodes until the key of "node" exceeds "key"
// new node should then be between "prev" and "node"
while ((node != NULL) && (node->key < key)) {
    prev = node;  //already locked
    node = node->next;
    //locking 2 nodes each time
    if (node != NULL){
        if(pthread_mutex_lock(&(node->mutex)) == 0){
            printf("failed locking\n");
            exit(1);
        }
    }
    if (node -> key < key){  //else: we need also preve staying locked for       the insertions
        if (pthread_mutex_unlock(&(prev->mutex)) != 0){
            printf("failed unlocking\n");
            exit(1);
        }
    }
}

// if node is same as our key - key already in list
if ((node != NULL) && (node->key == key)){

    if (node != NULL){  //not the end of the list
        if (pthread_mutex_unlock(&(node->mutex)) != 0){
            printf("failed unlocking\n");
            exit(1);
        }
    }

    if (prev != NULL){ //not the begining of the list
        if (pthread_mutex_unlock(&(prev->mutex)) != 0){
            printf("failed unlocking\n");
            exit(1);
        }
    }
    return 0;
}

// allocate new node and initialize it
setos_node* new_node = (setos_node*) malloc(sizeof(setos_node));
new_node->key = key;
new_node->value = value;
new_node->mutex = new_mutex;  //to change
if(pthread_mutex_init(&(new_node-> mutex), NULL) != 0){
    printf("failed init mutex");
    exit(1);
}


// place node into list
new_node->next = node;
prev->next = new_node;

if (node != NULL){ //not the end of the list
    if (pthread_mutex_unlock(&(node->mutex)) != 0){
        printf("failed unlocking\n");
        exit(1);
    }
}

if (prev != NULL){ //not the begining of the list
    if (pthread_mutex_unlock(&(prev->mutex)) != 0){
        printf("failed unlocking\n");
        exit(1);

    }
}

return 1;
}

你可以看到在第三行我定义了 pthread_mutex_t 到节点。但是这样做,每个新节点都会有相同的pthread_mutex_t吗?

我怎样才能做对?

是的,它将是同一个互斥量。

每次需要新的互斥量时,您都可以 malloc 一个新的互斥量元素,如下所示:

malloc(sizeof(pthread_mutex_t)))

像这样初始化:

pthread_mutex_init(m, NULL)