《多线程程序常见Bug剖析(上)》有8个想法

  1. “这个来自MySQL的Bug的根源就在于程序员认为线程1在执行S1时如果从thd->proc_info读到一个非NULL的值的话,在执行S2时thd->proc_info的值肯定也是非NULL的”

    应该是 “在S1完成非空判断后,thd->proc_info在S2中被修改为NULL,从而造成S1访问违例”

    不知是否我理解有误

    1. 原文的意思是”S1->S3->S2“这样的执行顺序会导致程序出错。即:在线程1的S1完成非空判断后,线程2的S3把它又改成NULL了,从而造成线程1的S2访问违例

  2. 我有个全局的变量
    struct S {
    int a;
    char b;
    }
    S g_s;
    如果我一个线程专门是修改g_s里面的值的,里面包括g_s.a = 1、g_s.a += 2等这样的操作,而另一个线程只是读取它的值的,用来做一些判断或给其他变量赋值等。这样子的话我需要对这个全局结构体的操作进行加锁吗

    1. g_s.a=1 这个操作在X86上是原子的,不需要加锁,但是加上volatile关键字比较好,防止编译器把新值只放在寄存器中;
      g_s.a+=2 这个操作在X86上不是原子的,但是如果其他线程只是读这个值,可以不需要加锁,因为其他线程最终还是会读到这个最新的值。同样,变量a还是加上volatile关键字比较好。
      可以参考:《多线程程序中操作的原子性》《为什么在多核多线程程序中要慎用volatile关键字?》

      1. 加不加锁除了要看单个操作是否原子,不是还要看g_s.a = 1、g_s.a += 2这两个操作是否为原子业务吗?加volatile关键字也只能保证值的可见性,并不能保证其原子性,如果不用锁把两个操作包起来,那另外一个线程还是会看到中间值吧的,感觉怎么加锁还是看具体业务需要。如果我的理解不对,请博主纠正。
        这网站的确实很多好并发的文章,可以好好学习学习,谢谢博主了

电子邮件地址不会被公开。 必填项已用*标注