原子加载/保存在 C 结构 (GCC) 问题上



尝试我的运气,使无锁的单链表实现。

typedef _Atomic struct _node
  {
    void *data;
    struct _node *next;
  } Node;

这是否也使结构的所有成员都具有原子_Atomic?

void add_head ( Linked_list* list, void* data )
{
  if ( debugging )
  {
      printf ( "%sn", __func__ );
  }
  Node *node = ( Node* ) calloc ( 1, sizeof (Node ) );
  //init_node_mutex(node);
  //lock_node_mutex(node);
  atomic_exchange ( &node->next, NULL );
  atomic_exchange ( &node->data, data );
  if ( list->head == NULL )
  {
      Node* the_tail = atomic_load ( &list->tail );
      //  lock_node_mutex ( the_tail );
      atomic_exchange ( &node->next, NULL );
      atomic_compare_exchange_weak ( &list->tail, the_tail, node );
      //unlock_node_mutex ( the_tail );
  }
  else
  {
      Node* the_next = atomic_load ( &node->next );
      // lock_node_mutex ( the_next );
      atomic_compare_exchange_weak ( &node->next, the_next, list->head );
      // unlock_node_mutex ( the_next );
  }
  Node* the_head = atomic_load ( & list->head );
  //lock_node_mutex ( the_head );
  atomic_store ( &list->head, node );
  atomic_store ( &list->current, node );
  //unlock_node_mutex ( the_head );
  //unlock_node_mutex(node);
  atomic_fetch_add ( &list->size, 1 );
}

用法是否atomic_load和atomic_store正确?

好吧,我争论过是将其作为"评论"还是"答案"发布,但我要在这里休息。

我的直觉相当尖叫,"你正在执行的单个操作是否是"原子的"并不重要,因为你连续执行许多操作,以完成你最终想要做的事情。即使这些单独的步骤是"原子的",整个操作也不是。

"原子"操作是使用专门的机器指令(例如 x86 上的LOCK前缀或大铁上的"比较和交换"指令)来执行单个操作的操作,以便没有其他 CPU(或内核)干扰该单个操作。

但是,你不能在"单个指令"中做你想做的事情,无论是否原子。

因此,我诚挚地建议你现在放弃你现在的课程,把那些"互斥"调用放回去,去掉"互斥"。您的代码(以及所有像这样的代码...)需要这些互斥体。在我看来,你正在追逐一只白兔在死胡同里。

(顺便说一下,"互斥"操作有时会很好地利用这些"原子指令",所以它们可能比你担心的要高效得多。

除了@MikeRobinson的评论之外,我想补充一点,虽然你的代码是"无锁的",因为它不包含任何明确的锁使用,但它现在(有点讽刺地)不再是线程安全的。编写无锁代码非常困难。我建议通读本文以获得对世界的鸟瞰图,然后阅读本文以获取一些细节或本书的第7章(这是C++)。您可以随时查看Boost.LockFree的来源以获取灵感。

相关内容

  • 没有找到相关文章

最新更新