x86指令集中lock前缀的意义

简介: 接上篇(https://yq.aliyun.com/articles/59019),对一个变量进行加法操作,可以是3条指令,也可以是1条指令。区别在于,1条指令属于原子操作,不会被打断,那是不是只要1条指令的形式,多线程之间就不需要加锁了呢?我们先试试看。 #include

接上篇(https://yq.aliyun.com/articles/59019 ),对一个变量进行加法操作,可以是3条指令,也可以是1条指令。区别在于,1条指令属于原子操作,不会被打断,那是不是只要1条指令的形式,多线程之间就不需要加锁了呢?我们先试试看。(以下代码仅适用于x86平台,gcc编译器)

#include <stdio.h>
#include <pthread.h>

int count = 0;

void *add(void *arg)
{
    int i;

    for (i = 0; i< 10000; i++) {
        asm(
            "addl $1, %0 \n"
            : : "m"(count) : );
    }
}

int main(int argc, char *argv[])
{
    pthread_t t1, t2;

    pthread_create(&t1, NULL, add, NULL);
    pthread_create(&t2, NULL, add, NULL);

    pthread_join(t1, NULL);
    pthread_join(t2, NULL);

    printf("%d\n", count);
    return 0;
}

然后运行:
images51

这是在一个多核处理器且支持对称多处理的系统上运行的结果。可见很大概率上,仍然存在同步问题。那为什么某些情况又能得到20000这个正确结果呢?鬼才知道,只能靠瞎猜。

多核多线程情况下,即便修改操作是单条指令,由于存在并发运行,也不能保证其原子性。幸好有taskset这个程序,可以设置cpu亲和性,我们先将其设置到单核试试看。

images52

嗯貌似完美。

那如果亲和性设置成两个核心呢?

images53

果然,有一定概率出现同步问题。

好了,文章要结束了,总得回到标题,类似电影要到时间了,反派再强大,也得找个方式被灭掉。lock前缀的意义在于,在多核且支持对称多处理的系统上,对于接下来的那条指令,能够保证其原子性。注意lock并不是能够往各个指令面前加的。至于如何保证了原子性,鬼才知道。

我们把add函数改写下:

  for (i = 0; i< 10000; i++) {
        asm(
            "lock \n"
            "addl $1, %0 \n"
            : : "m"(count) : );
    }

再运行几遍:

images54

好了,像是那么回事了。

目录
相关文章
|
4月前
|
存储 程序员
【汇编】Loop指令、段前缀
【汇编】Loop指令、段前缀
103 0
【汇编】Loop指令、段前缀
|
4月前
|
存储 安全 C++
《C++ Concurrencyin Action》第6章--基于锁的并发数据结构设计
《C++ Concurrencyin Action》第6章--基于锁的并发数据结构设计
《C++ Concurrencyin Action》第6章--基于锁的并发数据结构设计
|
10月前
|
Java
synchronize 三大作用、三大用法
synchronize 三大作用、三大用法
73 0
|
5月前
|
Java
多线程并发之显示锁Lock与其通信方式Condition源码解读
多线程并发之显示锁Lock与其通信方式Condition源码解读
23 0
|
6月前
|
存储 缓存 算法
从CPU缓存结构到原子操作-1
从CPU缓存结构到原子操作
94 0
|
6月前
|
存储 缓存 编译器
从CPU缓存结构到原子操作-2
从CPU缓存结构到原子操作
102 0
|
7月前
|
Java
lock和synchtonized的区别
lock和synchtonized的区别
|
9月前
|
缓存 安全 Java
volatile底层的实现原理:volatile关键字的作用、内存模型、JMM规范和CPU指令
volatile底层的实现原理:volatile关键字的作用、内存模型、JMM规范和CPU指令
124 0
KONGSBERG RCU502 设置和访问数字的存储器指令
KONGSBERG RCU502 设置和访问数字的存储器指令
69 0
KONGSBERG RCU502 设置和访问数字的存储器指令
|
Linux
Linux的互斥锁、条件锁的用法
Linux的互斥锁、条件锁的用法
98 0