问题标签 [atomic]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
4 回答
5317 浏览

java - AtomicReference.compareAndSet() 用于确定什么?

假设您有以下课程

然后执行以下代码

在最后一行中,该方法while (!stats.compareAndSet(prev, newValue))如何确定和之间的相等性?类是实现方法所必需的吗?如果不是,为什么?javadoc 声明如下compareAndSetprevnewValueAccessStatisticsequals()AtomicReference.compareAndSet

如果当前值 == 预期值,则自动将值设置为给定的更新值。

...但是这个断言似乎很笼统,我在 AtomicReference 上阅读的教程从未建议为包装在 AtomicReference 中的类实现 equals()。

如果需要封装在 AtomicReference 中的类来实现 equals(),那么对于比AccessStatistics我想象的更复杂的对象,同步更新对象而不使用 AtomicReference 的方法可能会更快。

0 投票
1 回答
1627 浏览

unix - 文件读写锁定和取消链接

我有以下问题。我想创建一个基于文件系统的会话存储,其中每个会话数据都存储在以会话 ID 命名的简单文件中。

我想要以下 API: write(sid,data,timeout), read(sid,data,timeout),remove(sid) 其中 sid==file name, 另外我想要某种可以删除所有超时会话的 GC。

如果您使用单个进程,则任务非常简单,但在使用多个进程甚至通过 NFS 时绝对不是微不足道的。

我想到的最简单的解决方案是:

文件取消链接适用于文件名和文件锁适用于文件描述符的最大问题。因此,上述情况在以下情况下不起作用:

有人知道如何解决此类问题吗?是否有任何技巧可以结合文件锁定和文件删除或对文件进行原子操作?

笔记:

  • 我不想使用数据库,
  • 我正在寻找 Unix 的解决方案
  • 解决方案应适用于标准 POSIX 调用,如 fcnl、打开、关闭、取消链接

谢谢。

澄清主要问题是对文件的操作(名称 - 取消链接)应该通过文件描述符的操作原子地完成 - 锁定:

  • 打开,取消链接——处理文件
  • fnctl -- 处理描述符
0 投票
2 回答
1656 浏览

linux - 如何验证原子写入?

我一直在努力搜索(在 S[O|F|U] 网络和其他地方),并认为这是一个不常见的问题。我正在使用运行 Debian Linux 2.6.28-4 的 Atmel AT91SAM9263-EK 开发板(ARM926EJ-S 内核,ARMv5 指令集)。我正在使用(我相信)tty 驱动程序与RS-485 串行控制器通信。我需要确保写入和读取是原子的。几行源代码(在本文末尾相对于内核源安装目录列出)暗示或隐含地说明了这一点。

有什么方法可以验证向/从该设备写入/读取实际上是原子操作吗?或者, /dev/ttyXX 设备是否被视为 FIFO 并且参数到此结束?仅仅相信代码正在执行它提出的这一主张似乎是不够的——就在今年 2 月,freebsd 被证明缺乏对小行的原子写入. 是的,我意识到 freebsd 与 Linux 并不完全相同,但我的观点是,仔细确定并没有什么坏处。我能想到的就是继续发送数据并寻找一个排列——我希望有一些更科学的东西,理想情况下,是确定性的。不幸的是,我完全不记得以前大学时代的并发编程课程。我会非常感激在正确方向上的一记耳光或推搡。如果您选择回复,请提前感谢您。

亲切的问候,

杰斯


驱动程序/char/tty_io.c:1087


拱/臂/包括/asm/bitops.h:37


驱动程序/串行/serial_core.c:2376

此外,来自 man write(3) 文档:

尝试写入管道或 FIFO 有几个主要特征:

  • 原子/非原子:如果在一个操作中写入的全部量没有与来自任何其他进程的数据交错,则写入是原子的。当有多个写入器向单个读取器发送数据时,这很有用。应用程序需要知道可以以原子方式执行的写入请求有多大。此最大值称为 {PIPE_BUF}。本卷 IEEE Std 1003.1-2001 没有说明超过 {PIPE_BUF} 字节的写入请求是否是原子的,但要求 {PIPE_BUF} 或更少字节的写入应该是原子的。
0 投票
4 回答
21637 浏览

sql - Oracle SQL:如何读取和增加字段

我正在重构企业应用程序的数据导入过程,并遇到了一个片段,我想找到一个更好的解决方案。导入数据时,我们必须为每个数据集创建一个唯一实体,并且在字段中有一个计数器用于按顺序分配此 ID。您阅读该字段以获取下一个空闲 ID,然后将其递增以准备下一次。

目前,这是在原始应用程序中分两步完成的,用“C”编写:

如果多个进程做同样的事情,显然这里存在竞争条件。

编辑:重要的并存条件:我无法触及数据库/字段定义,这排除了序列。

我们正在用 perl 重写,我想做同样的事情,但更好。原子解决方案会很好。不幸的是,我的 SQL 技能有限,所以我求助于集体智慧 :-)

0 投票
5 回答
8424 浏览

c# - C#如何保证读/写操作的原子性?

boolC# 规范在第 5.5 节中规定,对某些类型(即、charbytesbyteshortushortuintint、和引用类型)的读写float保证是原子的。

这引起了我的兴趣。你怎么能那样做?我的意思是,如果我想让读写看起来是原子的,我的个人经验只是告诉我锁定变量或使用障碍;如果每次读/写都必须完成,那将是性能杀手。然而,C# 做了类似的事情。

也许其他语言(如 Java)可以做到这一点。我真的不知道。我的问题并不是真的针对特定语言,只是我知道 C# 可以做到。

我知道它可能必须处理某些特定的处理器指令,并且可能无法在 C/C++ 中使用。但是,我仍然想知道它是如何工作的。

[编辑]说实话,我相信在某些情况下读写可能是非原子的,就像一个 CPU 可以访问一个内存位置,而另一个 CPU 正在那里写入。这是否仅在 CPU 无法一次处理所有对象时发生,例如因为它太大或因为内存未在正确的边界上对齐?

0 投票
6 回答
4856 浏览

c++ - 如何确保成员是 4 字节对齐的?

为了使用 OSAtomicDecrement(mac 特定的原子操作),我需要提供一个 4 字节对齐的 SInt32。

这种烹饪方法有用吗?是否有另一种方法来处理对齐问题?

0 投票
4 回答
7645 浏览

c++ - Mac OS X 上的原子增量

我在 Mac OS X 上搜索了原子递增和递减运算符并找到了“OSAtomic.h”,但您似乎只能在内核空间中使用它。

Jeremy Friesner指给我一个跨平台的原子计数器,他们在其中使用 OS X 上的汇编或互斥锁(据我了解 ifdefs 的交错)。

没有类似InterlockedDecrementatomic_dec()在 OS X 上的东西吗?

0 投票
3 回答
203 浏览

validation - 一种检查行不存在并将其插入原子的常用方法?

我有一个网络应用程序。在其中处理表单的流程如下:

  1. 证实
  2. 列出错误或插入/更新数据

在这个特定的场景中,我正在开发一个用户注册过程,但我试图为所有类型的表单找到一个通用的解决方案,基于检查数据库表中唯一值的可用性。

在此用户注册中,用户的登录名必须是唯一的。在验证阶段,应用程序检查其在数据库表中的可用性,如果可用则插入一行。还有其他字段也必须验证,例如密码和密码确认。所有验证在一个 HTTP 请求中发生一次。

问题是我不能确定应用程序检查其可用性之后,在第一个用户的进程插入它之前,它不会被另一个用户在并行进程中使用。我知道两个用户在同一毫秒内输入相同登录名的可能性非常小,但有一天可能会出现这种情况,即数千名用户同时向某个表单输入数据。

如果验证已经通过,用户不应该看到一些错误消息说他的登录已经注册。

我要解决的问题是确保唯一值在检查其可用性之后并将其插入一个HTTP 请求之前可用。另一个用户注册了相同的唯一登录名,而第一个用户弄乱了他的密码并且密码确认不一样,这没关系。

使用现有行可以轻松解决此问题,因为我可以 SELECT 它 FOR UPDATE 并且它将在事务期间被锁定。但是我不能对不存在的行做同样的事情。那就是问题所在。我该如何解决这个问题?


以下是我知道的一些解决方案。我不确定其中哪一个是最好的。另外,我不确定我知道最好的方法,所以请分享你知道的方法。

表锁定

过去我已经用表锁定解决了这个问题,但我不确定这是不是最好的方法。过程是这样的:

  1. 锁定表以进行写入
  2. 检查可用性
  3. 返回错误或插入行
  4. 解锁桌子

有人说锁定整个表是最糟糕的解决方案。也许是这样,但这是我自己想出的唯一可行的方法。

锁只在一个 HTTP 请求期间保留,当然不会在几个请求之间保留。

插入并捕获错误

这种方式是其他一些人向我建议的。他们建议将该列设为唯一索引列,并在两个阶段分别验证和检查唯一性。过程是这样的:

  1. 验证数据
  2. 如果验证成功,则插入该行
  3. 如果插入行失败显示唯一值不可用的错误

当然,我已将该列设为唯一索引列。但这并不意味着我想使用数据库的能力在验证时抛出错误;它应该在应用程序级别完成。

我不喜欢这种方式,因为我不喜欢这种情况下的 try-and-catch-an-exception 方式,因为在检查值的可用性并插入它的过程中没有任何异常。我认为它应该采用检查和保留和插入的方式。我认为验证用户输入不应该基于异常,因为用户输入错误并没有什么异常。

我可能错了,但这是我目前的观点。如果你认为我明显错了,请告诉我为什么。

0 投票
6 回答
752 浏览

multithreading - 您是否期望未来的 CPU 代不会缓存一致?

我正在设计一个程序,我发现假设隐式缓存一致性会使设计变得容易得多。例如,我的单个编写器(始终是同一个线程)多个读取器(始终是其他线程)场景没有使用任何互斥锁。

对于当前的 Intel CPU 来说,这不是问题。但我希望这个程序至少在未来十年(软件时间很短)产生收入,所以我想知道你是否认为这可能是未来 cpu 架构的问题。

0 投票
4 回答
32564 浏览

c# - 引用分配是原子的,那么为什么需要 Interlocked.Exchange(ref Object, Object)?

在我的多线程 asmx Web 服务中,我有一个我自己的 SystemData 类型的类字段 _allData,它由少数组成List<T>Dictionary<T>标记为volatile. 系统数据 ( _allData) 不时刷新一次,我通过创建另一个名为的对象newData并用新数据填充它的数据结构来做到这一点。完成后,我只是分配

这应该可以工作,因为分配是原子的,并且引用旧数据的线程继续使用它,而其余的线程在分配后就拥有新的系统数据。但是我的同事说volatile我应该使用关键字和简单的赋值,而不是使用,InterLocked.Exchange因为他说在某些平台上不能保证引用赋值是原子的。此外:当我将the _allData字段声明volatile

产生警告“对 volatile 字段的引用不会被视为 volatile” 我应该怎么想?