美文网首页
lock-free的一个简单的例子分析

lock-free的一个简单的例子分析

作者: Teech | 来源:发表于2019-07-24 15:21 被阅读0次

看到一篇关于lock-free的文章 https://preshing.com/20120612/an-introduction-to-lock-free-programming/
里面有段这个代码,X的初始值为0,让读者思考,当两个线程运行这段代码时,如何使得两个线程都陷入死循环。
Here’s a simple example of an operation which contains no mutexes, but is still not lock-free. Initially, X = 0. As an exercise for the reader, consider how two threads could be scheduled in a way such that neither thread exits the loop.

while (X == 0)
{
    X = 1 - X;
}

我反汇编下这段代码,这样就便于理解为何这段代码是线程不安全的。

00000000004008b6 <worker>:
  4008b6:   55                      push   %rbp
  4008b7:   48 89 e5                mov    %rsp,%rbp
  4008ba:   48 89 7d f8             mov    %rdi,-0x8(%rbp)
  4008be:   eb 15                   jmp    4008d5 <worker+0x1f>
  4008c0:   8b 05 c6 07 20 00       mov    0x2007c6(%rip),%eax        # 60108c <x>
  4008c6:   ba 01 00 00 00          mov    $0x1,%edx
  4008cb:   29 c2                   sub    %eax,%edx
  4008cd:   89 d0                   mov    %edx,%eax
  4008cf:   89 05 b7 07 20 00       mov    %eax,0x2007b7(%rip)        # 60108c <x>
  4008d5:   8b 05 b1 07 20 00       mov    0x2007b1(%rip),%eax        # 60108c <x>
  4008db:   85 c0                   test   %eax,%eax
  4008dd:   74 e1                   je     4008c0 <worker+0xa>
  4008df:   b8 00 00 00 00          mov    $0x0,%eax
  4008e4:   5d                      pop    %rbp
  4008e5:   c3                      retq  

因为初始值为0,即 0x2007c6(%rip)的内存处值为0

  1. 假设线程A和线程B都运行到路径:
    4008be -->4008d5-->4008db-->4008dd-->4008c0
    那么当前状态为0x2007b7(%rip)内存值为0,线程A和线程B的%eax寄存器的内容为0
  2. 线程A继续运行,此刻线程B并没有运行:
    4008c0-->4008c6-->4008cb-->4008cd-->4008cd-->4008cf
    当前状态为0x2007b7(%rip)内存值为1,线程A的%eax寄存器内容为1,线程B的%eax的内容为0.
  3. 线程B继续运行,此刻线程A并没有运行:
    4008c0-->4008c6-->4008cb-->4008cd-->4008cd-->4008cf
    当前状态为0x2007b7(%rip)内存值为0,线程A的%eax寄存器内容为1,线程B的%eax的内容为0.
  4. 线程A运行4008d5
    当前状态为0x2007b7(%rip)内存值为0,线程A的%eax寄存器内容为0,线程B的%eax的内容为0.
  5. 最后线程A和线程B陆续运行4008db,两个判断%eax为0,设置条件码ZF,然后继续循环下去了。

要理解这里,学会利用读懂汇编代码很有用处的。

这段c代码用gcc O1优化后,汇编如下

  4008e6:   83 3d 9f 07 20 00 00    cmpl   $0x0,0x20079f(%rip)        # 60108c <x>
  4008ed:   75 0a                   jne    4008f9 <worker+0x13>
  4008ef:   c7 05 93 07 20 00 01    movl   $0x1,0x200793(%rip)        # 60108c <x>
  4008f6:   00 00 00 
  4008f9:   b8 00 00 00 00          mov    $0x0,%eax
  4008fe:   c3                      retq   

相关文章

网友评论

      本文标题:lock-free的一个简单的例子分析

      本文链接:https://www.haomeiwen.com/subject/blmxrctx.html