linux指针赋值原子,x86_64处理器的指针赋值是原子操作吗?

如题, x86_64处理器的指针赋值是原子操作吗?

说实话我很讨厌参与讨论那些似乎不确定东西,倒不是说我对未知不敬畏,而是参与讨论的人大多数都是似懂非懂,对,我说的不确定性指的是参与讨论的人的认知的不确定,如果你自己都似懂非懂,那么我说什么你都可以反驳我,说些 “貌似,可能,并不绝对” 的词汇来让事情变得混乱。

所以说,我的意思是, 以Intel的手册为准。 我觉得我应该收回上面的那句 “which is a pointer assignment operation, on the x86_64 platform which is an atomic operation.” 然后重新说出个所以然来。

有了这段 权威描述 ,本文似乎该结束了。

但是…

show me the code 是个金句,它鄙视的是 talk, 因为 talk is cheap.

那好吧,按照这样看来,上面那一段都是废话,非常cheap,那么下面就用代码说话吧。

声明一下:

以下无术语,也不再引用任何cheap的东西。

本文虽然以“指针赋值”为例,但其实任何“int,long,long long”赋值均试用 。

我在代码里强转来强转去的,实际在暗示什么呢?CPU和内存不了解什么是指针,只有在执行的时候,一个unsigned long才会 变成 指针。

网络协议,序列化时,请 谨慎相信任何原子操作的承诺!

考虑一个指针p,两个或者多个线程分别对它进行赋值:

long *p;

// thread 1

p = a1;

// thread 2

p = a2

结果可以预期吗?如果你笃信指针赋值是原子操作,那么最终结果,p不是a1,便是a2,这是确定的。

然而Intel手册里说,如果指针p跨越了cacheling的边界,便不能保证赋值操作是原子的,为了复现Intel的说法,从而证明指针赋值并非原子的,只需要给出一个反例,即p既不是a1,也不是a2。

在编码之前,我们先查一下自己实验的机器上的cacheline的大小:

root@zhaoya-VirtualBox:~/xdp/msvc# cat root@zhaoya-VirtualBox:~# cat /sys/devices/system/cpu/cpu1/cache/index0/coherency_line_size

64

OK,64字节的cacheline,我们下面就制造一个跨越64字节边界的指针,直接看代码:

#include

#include

// 不让编译器自动扩充结构体对齐特征,这个在网络协议以及序列号操作中很常见。

#pragma pack(1)

struct pack {

// 60字节的padding

char unsued[60];

// cacheline仅剩下4字节,仅够装指针p的4字节,剩余4字节跨越到另一个cacheline

long *p;

};

#pragma pack()

// 内存对齐粒度最小为1字节,我设置64个元素的数组,总有一个元素恰好是在64字节边界的!

struct pack pa[64];

// 保存64字节边界的元素

struct pack *used;

long a = 0x1122334455667788;

long b = 0x8877665544332211;

void *write_value1(void *param)

{

for (;;) {

used->p = (long *)a;

// 不让编译器优化

asm volatile("" ::: "memory");

}

return NULL;

}

void *write_value2(void *param)

{

for (;;) {

used->p =(long *)b;

asm volatile("" ::: "memory");

}

return NULL;

}

int main(int argc, char **argv)

{

int i;

long *p;

pthread_t t1, t2;

// for循环找到那个64字节边界的pack结构体元素

for (i = 0; i < 64; i++) {

unsigned long addr;

addr = (unsigned long)&pa[i];

if (addr%64 == 0) {

// 赋值给used

used = (struct pack *)addr;

break;

}

}

pthread_create(&t1, NULL, write_value1, NULL);

pthread_create(&t2, NULL, write_value2, NULL);

while (1) {

p = used->p;

// 我们看能不能找到既不是a,又不是b的p

if (p != (long *)a && p != (long *)b) {

printf("%lx\n", (unsigned long)p);

}

}

return 0;

}

跑一下呗:

8899615b483992928ab4ed4b638f24e9.png

我的天!

这意味着什么?

这意味着不加锁的指针赋值,极其危险!

什么?难道编译器不帮忙?

编译器只能尽量帮忙,哦,对了,还有Linux内核的伙伴系统,slab系统,都只是尽量帮忙,其余的事,只能看造化。谁也不能保证你不会写出上面类似pack的结构体,因此结构体的字段布局非常重要。

即便这样,你也不能保证结构体对象恰好被载入你希望的位置,只要超过一个cacheline大小的结构体,内部字段的赋值就一定小心再小心:

加锁影响性能

不加锁怕跨越边界

说白了这就是个手艺活。

如果你想快速复现指针跨越cacheline的赋值非原子性,直接加个修饰即可:

// 你也可以直接用aligned来固化地址对齐特征,然则不真实!

struct pack pa __attribute__ ((aligned(64)));

...

int main(...

...

used = &pa;

不多说了,深入什么单条指令的原子执行,LOCK引脚,cache一致性原子操作粒度等等细节无益于解决实际问题,至于其它体系结构,摸都摸不到(我是说我自己),更显得纸上谈兵,到此为止了。

浙江温州皮鞋湿,下雨进水不会胖!

f5fdd7608baa8cefd6a32c4be7c2639e.png

2f629b3873c4a35a79c201f33b3e2cf3.png

dog250

博客专家

发布了1546 篇原创文章 · 获赞 4762 · 访问量 1057万+

他的留言板

关注

标签:x86,long,64,赋值,字节,指针,pack

来源: https://blog.csdn.net/dog250/article/details/103948307

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/563402.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

tecplot批量导出图片_批量导出Excel图片,用这招,半分钟干的活别人一整天完不成...

上个星期&#xff0c;我的一个同学向我求助。她是公司的HR&#xff0c;老板让她把员工信息表中的照片导出到文件夹中&#xff0c;然后打包发送给行政部的文员打印出来。她公司有5000多人&#xff0c;她复制粘贴了整整一个上午&#xff0c;才导出了200多张照片&#xff0c;而且还…

android动画超出圆角,Android关于Glide的使用(高斯模糊、加载监听、圆角图片)

高斯模糊、加载监听、圆角图片这些相信大家都很熟悉&#xff0c;那如何实现这些效果&#xff0c;请大家参考本文进行学习。1、引用compile com.github.bumptech.glide:glide:3.7.02、加载图片2.1 基本加载Glide.with(context).load(url).into(imageView);2.2 设置加载中和加载失…

填充table_Excel Power Query | 向下填充的逆过程

上期内容给大家讲解了关于图表精品图表 | Excel绘制“带有阈值分割的条形图和棒棒图”的制作方法。本期给大家讲解一下关于Power Query的知识 。如下图&#xff0c;将下面的数据向下填充逆过程。即将左侧的数据转换至右侧的数据。如果是从右往左的话是直接向下填充即可&#xf…

android中拖拽浮动按钮,Android自定义view实现拖拽选择按钮

本文实例为大家分享了Android实现拖拽选择按钮的具体代码&#xff0c;供大家参考&#xff0c;具体内容如下DragChooseDemo效果图Attributes属性(布局文件中的自定义属性)半径、文字大小、按钮个数注意配合使用&#xff0c;以达到最佳效果方法使用布局文件中的使用android:id&qu…

# 解析bt文件_磁力链接和BT种子使用方法

目前用的最多的是磁力链接和BT种子&#xff0c;不过好多人并不太会使用&#xff0c;因此写个教程给大家说明一下。何为磁力链接&#xff1a;简单地说&#xff0c;磁力链接是一种特殊链接&#xff0c;但是它与传统基于文件的位置或名称的普通链接(如http://xxx)不一样&#xff0…

easyexcel设置下拉选项不能覆盖_Wi-Fi经常掉线 这个设置要修改

在使用Wi-Fi的时候最大的问题是什么&#xff1f;小伙伴们肯定说&#xff0c;当然是掉线啦。Wi-Fi设备过多、路由器设置等问题造成的掉线断网问题咱们之前都说过了。有些小伙伴又反映自己的电脑在使用无线网络时&#xff0c;一段时间不用就会掉线&#xff0c;手机却一直连接很好…

google开源android工具,谷歌最强Android UI工具包霸榜Github,这份上手指南了解一下...

2019年&#xff0c;谷歌在I/O大会上公开开源了一个非捆绑工具包——Jetpack Compose&#xff0c;这是一个用于构建原生Android UI的现代化工具包。仅通过少量代码就能完成布局&#xff0c;且能够直接使用Kotlin来进行编写。Jetpack Compose工具包是围绕着composable函数来构建的…

重叠面积_重叠面积——动点产生的重叠面积问题

本文开始介绍重叠面积问题。顾名思义&#xff0c;此类问题主要是求两个几何图形的重叠部分的面积。解题的关键为画出图形&#xff0c;然后再表示面积。文中的中考真题选自以下地区&#xff1a;2019•资阳、2019•鸡西、2019黄冈【题1】(2019•资阳)在矩形ABCD中&#xff0c;连结…

鸿蒙os硬件要求,华为公布鸿蒙OS 2.0硬件安装要求:只要128K内存就能跑

9月10日下午&#xff0c;华为在东莞松山湖举办了2020开发者大会&#xff0c;鸿蒙OS 2.0正式发布。会后&#xff0c;华为软件部总裁王成录博士、华为软件部副总裁杨海松等接受了专访。谈及鸿蒙OS 2.0的规划&#xff0c;杨海松表示&#xff0c;大家非常期待的手机的Beta版本会在今…

几张一模一样的照片_两张一模一样的照片看起来却不一样!什么鬼?

原标题&#xff1a;两张一模一样的照片看起来却不一样&#xff01;什么鬼&#xff1f;近日&#xff0c;国外论坛Reddit上的两张照片火了&#xff0c;发布仅2天时间就吸引了200万人围观&#xff0c;不少网友都认为这是两张不同拍摄角度的照片&#xff0c;但其实它们一模一样&…

android rtsp 延时,ijkplayer 单视频流直播延迟问题解决过程

一开始我尝试是通过设置ijkplayer的参数去修改延迟&#xff0c;参数的修改能把ijkplayer的开播延迟拉到200ms左右&#xff0c;但是随着播放时间增加延迟也在增加&#xff0c;然后带着问题去网上寻找答案&#xff0c;找到暴走大牙和Gongjia两位大神的解决方案&#xff0c;但是这…

双系统android,如何在Android手机上实现双系统

1、必要工具和条件分区软件、读卡器、 官方boot.img 、boot解包打包工具、手机装了第三方recovery2、原理实现原理就是把sd卡分成4个区&#xff1a;1个正常存取文件区和3个系统区一样格式的区。sd卡上的system区里放了系统正常工作所需的文件&#xff0c;修改了内核启动挂载区&…

python接口测试框架django_开源~自研接口测试平台 Django2.0+Vue

接口测试平台从开始到放弃python3.6.3 Django 2.0.2框架版本更新&#xff1a;v2.3引入docker部署,由于采用的docker&#xff0c;基础镜像为centos&#xff0c;所以Windows下部署仍然可以使用定时任务docker-compose upv2.21.新增钉钉登录https://ding-doc.dingtalk.com/doc#/se…

香蜜台词共赴鸿蒙,香蜜台词斗法

1、凤凰&#xff0c;我们&#xff0c;还能回到从前吗。回不去了&#xff0c;再也回不去了&#xff0c;或许&#xff0c;我们可以从头开始。我终究是不能&#xff0c;也不愿放你走&#xff0c;留在我身边&#xff0c;不要再骗我&#xff0c;否则&#xff0c;我真的会跟你共赴鸿蒙…

postgresql中装gis插件_PostgreSQL插件PostGIS安装

参考官网 http://postgis.net/PostGis版本2.5.31.安装libxml2# yum install libxml2 libxml2-devel2.安装json-c# tar zxvf json-c-json-c-0.13.1-20180305.tar.gz# cd json-c-json-c-0.13.1-20180305# ./configure && make && make install3.安装protobuf-c# …

html5svg在线编辑器,SVG to Canvas在线转换工具

https://github.com/samsha/svg2canvascanvg.js是的确实有人在做这样的事&#xff0c;canvg.js 就是一个将SVG转换成Canvas的工具库&#xff0c;甚至有些SVG的动画效果也能得到实现&#xff0c;但是canvg.js存在很多问题&#xff1a;不可避免的SVG兼容问题SVG是一种很复杂的矢量…

python3 上传文件到目标机器_通过python模块实现服务器和本地机器之间快速拷贝文件...

在实际的开发过程中&#xff0c;很多时候我们都不直接在本机上开发&#xff0c;一般都在远程服务器上开发并运行程序。比如三胖在实际开发中就会使用到很多台服务器&#xff1a;我有一台笔记本电脑&#xff0c;通过 ssh 连接着很多台服务器&#xff0c;我需要经常在不同的服务器…

android 拼图课程设计,拼图游戏设计_课程设计报告.docx

IlIlIlIl学号16082202032016-2017学年 第一学期《Windows程序设计》课程设计报告题目:拼图游戏设计专业:班级:姓名:指导教师&#xff1a;成绩:学院二0—六年十一月十五日TOC \o "1-5" \h \z \o "Current Document" 仁设计目的与要求31. 111 目白勺????…

android 能调用gcc_如何在命令行下使用Android NDK交叉编译工具

我们知道,在Linux下可以使用gcc来把一份C代码编译成为Linux上的可执行程序, 如:$ gcc -o main.out main.c而Android平台提供了NDK工具包来交叉编译可以运行于Android系统中的应用程序, 它需要我们编写 Android.mk来配置编译选项和编译目标, 那么, 能否也像gcc那样直接在命令行下…

鸿蒙系统有那些上市,鸿蒙上市整套系统究竟意味着什么

大家期待的鸿蒙系统已经上市&#xff0c;首先鸿蒙系统从自家的生态产品适配&#xff0c;大家熟知的华为笔记本&#xff0c;华为手机&#xff0c;华为平板&#xff0c;华为手表等&#xff0c;相比目前市场上的操作系统&#xff0c;IOS&#xff0c;安卓&#xff0c;微软Windows&a…