2

对于具有多个读取器线程和单个写入器线程的场景,允许读取器读取稍微过时的数据,我编写了一个无锁控制流,如下所示,其最基本的伪代码形式如下所示:

GLOBAL_ATOMIC_POINTER shared_pointer

// Only called by the reader threads.
read()
    THREAD_LOCAL_POINTER read_pointer := shared_pointer
    return read_data_at(read_pointer)

// Only called by the writer thread.
write(input)
    THREAD_LOCAL_ARRAY array
    THREAD_LOCAL_POINTER write_pointer := shared_pointer
    if write_pointer == location_of_last_element(array)
        write_pointer := location_of_first_element(array)
    else
        write_pointer := location_of_next_element(array, write_pointer)
    write_data_at(write_pointer, input)
    shared_pointer := write_pointer

让我们调用MAX_READING_DURATION一个调用read()可以完成的最长时间,以及一个调用可以完成MIN_WRITING_DURATION的最短时间write()

现在,shared_pointer保证是原子的,只要MAX_READING_DURATION < ELEMENT_COUNT(ARRAY) * MIN_WRITING_DURATION,这个方案应该是完全安全的。

还是我忽略了什么?如果不是,我敢肯定这是众所周知的事情,我想知道正确的术语,所以当我向其他人解释/倡导这种方法时,我可以使用它。

4

1 回答 1

1

足够的内存和写入线程的总数不是确定什么可以无锁和不能无锁的标准。

无锁编程的一个重要特性是,如果您挂起单个线程,它将永远不会阻止其他线程通过自己的无锁操作取得进展。

但是,更重要的是:您的(单编写器)代码需要遵守的主要特性是“顺序一致性”:

顺序一致性意味着'所有线程都同意内存操作发生的顺序,并且该顺序与程序源代码中的操作顺序一致'。

如果代码不能保证顺序一致性,它必须防止内存重新排序。(这里有更多关于内存重新排序的信息:http: //preshing.com/20120515/memory-reordering-caught-in-the-act/

最后,我建议查看这些资源以深入了解无锁多线程编程概念: http ://concurrencykit.org/presentations/lockfree_introduction/#/ http://www.drdobbs.com/lock-free -数据结构/184401865

祝你好运!

于 2016-06-23T06:19:27.530 回答