您是否可以通过保证多个线程不能访问同一内存来避免锁定?

Eld*_*bob 41 c c++ multithreading lock-free

假设我有一个大型数组,我想用多个线程处理内容.如果我将每个线程委托给特定的部分,保证不重叠,这是否消除了锁定的需要,假设线程不访问数组外的任何其他内存?

像这样的东西(伪代码):

global array[9000000];

do_something(chunk) {
    for (i = chunk.start; i < chunk.end; i++)
        //do something with array
}

main() {
    chunk1 = {start: 0, end: 5000000};
    chunk2 = {start: 5000000, end: 9000000};

    start_thread(thread1, do_something(chunk1));
    start_thread(thread2, do_something(chunk2));

    wait_for_join(thread1);
    wait_for_join(thread2);
    //do something else with the altered array
}
Run Code Online (Sandbox Code Playgroud)

Com*_*sMS 31

在符合C++ 11的编译器中,这是安全的[intro.memory](§1.7):

存储器位置是标量类型的对象或相邻位域的最大序列,所有这些都具有非零宽度.[...]两个执行线程(1.10)可以更新和访问单独的内存位置,而不会相互干扰.

C11在§3.14中给出了相同的保证(它们甚至使用相同的措辞).

在C++ 03编译器中,这不能保证按标准工作,但如果编译器提供与扩展类似的保证,它仍然可以工作.

  • 是否有一个编译器在C++ 03中没有提供这种行为?虽然它虽然不是正式的,但它在现代硬件上是一个非常常见的功能...... (4认同)

Mik*_*our 18

是的:如果您可以保证没有两个线程可以访问同一个元素,那么就不需要进一步同步了.

如果两个线程在没有同步的情况下访问相同的内存位置(至少其中一个修改它),则只存在冲突(因此可能存在数据争用).

(注意:这个答案基于C++ 11内存模型.我刚刚注意到你也在询问第二种语言;我相信C11指定了一个非常相似的内存模型,但不能肯定地说答案对C也有效.对于这两种语言的旧版本,线程安全性与实现有关.)


Sca*_*nth 8

是的,你的确可以.

TCMalloc就是一个很好的例子.