我现在正在学习有关互斥锁和多线程数据结构的知识。我正在尝试实现一个并发排序的链表数据结构,该结构支持插入,删除,打印和释放整个列表,并且我已经编写了所有功能。不幸的是,我对线程锁的概念还很陌生。我尝试使用移交锁定实现排序后的链表,但是元素的插入和删除均不起作用(我在Red Hat VM上尝试了这些功能),而且我也不知道print功能是否正确。在Linux上调试时遇到问题,因为我还很陌生。有什么建议可以更正我的代码吗?请注意,我正在寻找有关如何以最佳方式实现越区切换手动锁定的说明,而不是将整个代码作为答案。 提前致谢。
concurrent_list.h:
函数和结构声明的头文件。
typedef struct node node;
typedef struct list list;
list* create_list();
void delete_list(list* list);
void print_list(list* list);
void insert_value(list* list, int value);
void remove_value(list* list, int value);
void count_list(list* list, int (*predicate)(int));
concurrent_list.c
该文件执行的头文件中的功能和 还有更多功能。
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include "concurrent_list.h"
struct node {
int value;
node* next;
pthread_mutex_t lock; // hand over hand implies a lock for every node
};
struct list {
node* head;
};
// print the value of a node
void print_node(node* node)
{
if(node)
{
printf("%d ", node->value);
}
}
// create a new empty list
list* create_list()
{
list* new_list = (list*)malloc(sizeof(list));
if(new_list == NULL)
{
return NULL;
}
new_list->head = NULL;
return new_list;
}
// delete the entire list (lock the current element for other threads)
void delete_list(list* list)
{
node* temp = list->head;
node* curr;
if(temp == NULL) return;
while (temp != NULL)
{
pthread_mutex_lock(&(temp->lock));
curr = temp;
free(curr);
temp = temp->next;
}
}
// insert function for a new value if a value already exists then do nothing
// lock the current and previous elements for other threads
void insert_value(list* list, int value)
{
if(list == NULL) return;
node* new_node = (node*)malloc(sizeof(node));
if(new_node == NULL) return;
new_node->value = value;
if(list->head == NULL)
{
list->head = new_node;
list->head->next = NULL;
}
node* prev = list->head;
pthread_mutex_lock(&prev->lock);
node* curr = prev->next;
if(curr == NULL)
{
if(prev->value > value)
{
new_node->next = prev;
prev->next == NULL;
}
else if(prev->value < value)
{
prev->next = new_node;
new_node->next = NULL;
}
else
{
free(new_node);
}
pthread_mutex_unlock(&prev->lock);
return;
}
pthread_mutex_lock(&curr->lock);
while(curr->value < value)
{
pthread_mutex_unlock(&prev->lock);
prev = curr;
curr = prev->next;
if(curr == NULL)
{
pthread_mutex_unlock(&prev->lock);
return;
}
pthread_mutex_lock(&curr->lock);
}
if(curr->value == value)
{
pthread_mutex_unlock(&curr->lock);
pthread_mutex_unlock(&prev->lock);
return;
}
new_node->next = curr;
prev->next = new_node;
pthread_mutex_unlock(&curr->lock);
pthread_mutex_unlock(&prev->lock);
}
//delete the first appearance of a value in the list if it exists in the list
// lock the current and previous elements for other threads
void remove_value(list* list, int value)
{
if(list == NULL || list->head == NULL) return;
node* prev = list->head;
pthread_mutex_lock(&prev->lock);
node* curr = prev->next;
if(curr == NULL)
{
if(prev->value == value)
{
prev->next == NULL;
}
pthread_mutex_unlock(&prev->lock);
return;
}
pthread_mutex_lock(&curr->lock);
while(curr->value < value)
{
pthread_mutex_unlock(&prev->lock);
prev = curr;
curr = prev->next;
if(curr == NULL)
{
pthread_mutex_unlock(&prev->lock);
return;
}
pthread_mutex_lock(&curr->lock);
}
if(curr->value == value)
{
prev->next = curr->next;
}
pthread_mutex_unlock(&curr->lock);
pthread_mutex_unlock(&prev->lock);
}
//print the entire list
// lock the current element for other threads
void print_list(list* list)
{
node* curr = list->head;
while(curr != NULL)
{
pthread_mutex_lock(&curr->lock);
print_node(curr);
pthread_mutex_unlock(&curr->lock);
curr = curr->next;
}
printf("\n");
}
// print how many nodes in the list satisfy a given predicate function
// lock the current element for other threads
void count_list(list* list, int (*predicate)(int))
{
int count = 0;
node* curr = list->head;
while(curr != NULL)
{
pthread_mutex_lock(&curr->lock);
if(predicate(curr->value))
{
count++;
}
pthread_mutex_unlock(&curr->lock);
curr = curr->next;
}
printf("%d items were counted\n", count);
}