【发布时间】:2019-11-01 19:00:13
【问题描述】:
我想要一个像单链表一样工作的并发数据结构,只需要append 和remove_iterator 操作。最后,一个线程将iterate所有节点。根据我的研究,我得到了一个 implementation,它具有带有单链表的 append、remove_value 和 search_value 操作。它基于Harris' algorithm。
问题在于,在 Harris 算法中,remove_value 仅将节点标记为逻辑删除,而没有实际删除它。 search_value 实际上负责删除逻辑删除的节点。但是由于我的用例没有search 操作。我保留了一个很长的列表,其中包含许多逻辑删除的节点。只是在多线程中效率不高,因为删除节点的所有工作都放在单个线程中的iterate 操作上。
我想知道是否还有其他适合我需要的实现。任何建议表示赞赏。
如果不是,我想知道我是否可以使用带有无锁堆栈实现的free-list 来为这种特殊情况实现一些东西。在这种情况下,append 操作变为pop 空闲列表,将值放入节点或如果为空则附加到我们的列表中。 remove_iterator 操作变为标记逻辑上删除的节点,push 成为指向空闲列表的节点指针。
我认为无锁堆栈很容易实现。我可以在线使用一些implementations。
记住一些代码。
struct node_t {
node_t *next;
int deleted;
val_t val;
};
struct list_t {
node_t *head;
};
struct fl_node_t {
node_t *padding_1;
int padding_2;
fl_node_t *next; // assume sizeof(val_t) >= sizeof(fl_node_t*);
};
struct free_list_t {
fl_node_t * head;
};
void append(val_t val) {
fl_node_t *fl_head;
fl_node_t *fl_next;
node_t *head;
node_t *new_node
/* Try insert to one of the node in free-list */
if (free_list.head) {
do {
fl_head = free_list.head;
next = fl_head->next;
} while(!CAS(&free_list.head, fl_head, fl_next));
if (fl_head) {
fl_head->node->val = val;
return;
}
}
/* Append to head */
new_node = malloc(sizeof(node_t));
new_node.val = val;
new_node.deleted = 0;
do {
head = list.head;
new_node.next = head;
} while(!CAS(&list.head, head, new_node));
}
void remove(node_t *node) {
fl_node_t *fl_node;
fl_node_t *fl_head;
/* Mark logically deleted */
node->deleted = 1;
fl_node = (fl_node_t*) node;
/* Add to free-list */
do {
fl_head = free_list.head;
fl_node->next =fl_head;
} while(!CAS(&free_list.head, fl_head, fl_node));
}
【问题讨论】:
-
需要无锁的条件是什么?
-
许多线程同时处理同一个数据结构。非无锁作品。我有一个列表的全局锁定。表现不是很好。我绝对可以为每个节点切换到细粒度的锁定。但是,它可能会带来大量内存开销。互斥体是 0x40 字节,而我的 val_t 只是 0x8 字节。而且名单很大。
-
对于一些小的固定 N 和随机着色节点有 N 个锁怎么样?我不确定你是否可以用它来制定一个安全的锁定顺序协议,但这听起来很合理。
-
你的意思是以下。而不是一份清单。我可以使用 N 个列表和 N 个锁。并将值随机添加到列表之一。更新时,只需锁定正确的锁即可。这样,就不需要锁定顺序。我想我可以尝试使用新列表的变体,并在添加 N 个值时锁定。
-
听起来你需要三个操作:前向迭代、追加和remove_iterator。其中一些仅由一个线程执行吗?例如你有一个线程修改和一个线程阅读?还是一篇写多读?了解此类限制有助于找到解决方案。
标签: c multithreading atomic lock-free compare-and-swap