热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

当只对变量进行inc/decrementing时,互斥是必需的吗?-Isamutexnecessarywhenonlyinc/decrementingavariable?

Ihaveastructwithsomeintegersfield,like我有一个有一些整数场的结构,比如。structs{inta;intb;

I have a struct with some integers field, like

我有一个有一些整数场的结构,比如。

struct s {
    int a;
    int b;
    int c;
    int max;
};
struct s mystruct = {0, 0, 0, 0}; // Global var

And then I have N threads that sometimes have to do things like ++ or -- on the first three fields, and sometimes have to read them and then update the max field. Do I have to use a mutex here? And if yes, is it needed only when reading/updating max or always? Why? If I just increment or decrement the first three fields, does it matter if a thread runs before another?

然后我有N个线程它们有时需要做一些事情比如++或-在前三个字段上,有时需要读取它们然后更新max字段。我必须在这里使用互斥锁吗?如果是,它是否只需要在读取/更新max或always时?为什么?如果我只是增加或减少前三个字段,那么一个线程在另一个线程之前运行是否有关系?

3 个解决方案

#1


4  

You need to synchronize the access to the variables if the operations you are performing are not atomic. Consider a scenario of a single variable a having initial value of, say, 5. Now we have two threads T1 and T2, both want to increment it. How increment operation is broken down, in case it is not atomic (just an example, it could be some other way)?

如果正在执行的操作不是原子操作,则需要同步对变量的访问。考虑一个单变量a的初始值为5的场景。现在我们有两个线程T1和T2,都想增加它。如何分解递增操作,以防它不是原子操作(只是一个例子,它可以是其他的方法)?

1) Read a value into a temp location.
2) Increment and write the temp location back into a.

1)将一个值读入一个临时位置。2)递增并将临时位置写回a中。

Now consider a scenario T1 is performing this operation first, and then pre-empted by T2 after completing step 1 only:

现在考虑一种情形T1先执行这个操作,然后在完成第1步之后,在T2之前抢先一步:

T1: 1) Read a into temp1 => temp1=5
T2: 1) Read a into temp2 => temp2=5
T2: 2) Write temp2+1 into a => a=6
T1: 2) Write temp1+1 into a => a=6

1)将a读入temp1= > temp1=5 T2: 1)将a读入temp2= > temp2=5 T2: 2)将temp2+1写入a= > =6 T1: 2)将temp1+1写入a= > a=6

So the final value of a will be 6 and not 7 as you would expect.

a的最终值是6而不是7。

#2


9  

The universal rule of concurrency is this: If a memory location is accessed concurrently in a non-atomic way, and not all accesses are reads, then the accesses must be ordered. Ordering can be imposed either by serializing access through locking a mutex, or by some lower-level operation like an ordered atomic access or an ordered fence.

并发的通用规则是:如果以非原子方式并发访问内存位置,并且不是所有访问都被读取,那么访问必须被排序。可以通过锁定互斥对象来序列化访问,也可以通过一些低级操作(如有序原子访问或有序围栏)来强制排序。

The only time you're allowed to have unordered accesses if all of the accesses are reads. E.g. multiple threads can read a (non-atomic) constant without ordering.

如果所有访问都是读操作,那么唯一一次允许有无序访问。例如,多个线程可以读取(非原子的)常数而不进行排序。

#3


0  

If you have multiple threads updating global data then you should have mutex. You should use mutex in both cases in read and write. Only reading constant data have no issue.

如果您有多个线程更新全局数据,那么您应该有互斥对象。您应该在读写两种情况下都使用互斥锁。只读取常量数据没有问题。

If you avoid to use the mutex you will not get desired result because other threads will not get proper value. Have look on this When should we use mutex ?

如果您避免使用互斥对象,您将不会得到所需的结果,因为其他线程将得不到适当的值。看看这个,我们什么时候应该使用互斥?

Have look on example.

看例子。


推荐阅读
  • 本文讨论了clone的fork与pthread_create创建线程的不同之处。进程是一个指令执行流及其执行环境,其执行环境是一个系统资源的集合。在调用系统调用fork创建一个进程时,子进程只是完全复制父进程的资源,这样得到的子进程独立于父进程,具有良好的并发性。但是二者之间的通讯需要通过专门的通讯机制,另外通过fork创建子进程系统开销很大。因此,在某些情况下,使用clone或pthread_create创建线程可能更加高效。 ... [详细]
  • 本文介绍了九度OnlineJudge中的1002题目“Grading”的解决方法。该题目要求设计一个公平的评分过程,将每个考题分配给3个独立的专家,如果他们的评分不一致,则需要请一位裁判做出最终决定。文章详细描述了评分规则,并给出了解决该问题的程序。 ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • 基于Socket的多个客户端之间的聊天功能实现方法
    本文介绍了基于Socket的多个客户端之间实现聊天功能的方法,包括服务器端的实现和客户端的实现。服务器端通过每个用户的输出流向特定用户发送消息,而客户端通过输入流接收消息。同时,还介绍了相关的实体类和Socket的基本概念。 ... [详细]
  • 本文介绍了Oracle存储过程的基本语法和写法示例,同时还介绍了已命名的系统异常的产生原因。 ... [详细]
  • 使用圣杯布局模式实现网站首页的内容布局
    本文介绍了使用圣杯布局模式实现网站首页的内容布局的方法,包括HTML部分代码和实例。同时还提供了公司新闻、最新产品、关于我们、联系我们等页面的布局示例。商品展示区包括了车里子和农家生态土鸡蛋等产品的价格信息。 ... [详细]
  • Linux重启网络命令实例及关机和重启示例教程
    本文介绍了Linux系统中重启网络命令的实例,以及使用不同方式关机和重启系统的示例教程。包括使用图形界面和控制台访问系统的方法,以及使用shutdown命令进行系统关机和重启的句法和用法。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 本文介绍了C#中生成随机数的三种方法,并分析了其中存在的问题。首先介绍了使用Random类生成随机数的默认方法,但在高并发情况下可能会出现重复的情况。接着通过循环生成了一系列随机数,进一步突显了这个问题。文章指出,随机数生成在任何编程语言中都是必备的功能,但Random类生成的随机数并不可靠。最后,提出了需要寻找其他可靠的随机数生成方法的建议。 ... [详细]
  • Python正则表达式学习记录及常用方法
    本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
  • 自动轮播,反转播放的ViewPagerAdapter的使用方法和效果展示
    本文介绍了如何使用自动轮播、反转播放的ViewPagerAdapter,并展示了其效果。该ViewPagerAdapter支持无限循环、触摸暂停、切换缩放等功能。同时提供了使用GIF.gif的示例和github地址。通过LoopFragmentPagerAdapter类的getActualCount、getActualItem和getActualPagerTitle方法可以实现自定义的循环效果和标题展示。 ... [详细]
  • 闭包一直是Java社区中争论不断的话题,很多语言都支持闭包这个语言特性,闭包定义了一个依赖于外部环境的自由变量的函数,这个函数能够访问外部环境的变量。本文以JavaScript的一个闭包为例,介绍了闭包的定义和特性。 ... [详细]
  • Whatsthedifferencebetweento_aandto_ary?to_a和to_ary有什么区别? ... [详细]
  • 欢乐的票圈重构之旅——RecyclerView的头尾布局增加
    项目重构的Git地址:https:github.comrazerdpFriendCircletreemain-dev项目同步更新的文集:http:www.jianshu.comno ... [详细]
  • 本文整理了Java面试中常见的问题及相关概念的解析,包括HashMap中为什么重写equals还要重写hashcode、map的分类和常见情况、final关键字的用法、Synchronized和lock的区别、volatile的介绍、Syncronized锁的作用、构造函数和构造函数重载的概念、方法覆盖和方法重载的区别、反射获取和设置对象私有字段的值的方法、通过反射创建对象的方式以及内部类的详解。 ... [详细]
author-avatar
小哥
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有