问题标签 [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.
multithreading - 原子指令和变量更新可见性
在最常见的平台上(最重要的是 x86;我知道有些平台的内存模型非常困难,几乎不能保证对多线程有用,但我不关心罕见的反例),下面的代码安全吗?
线程 1:
线程 2:
假设原子操作的标准、合理实现:
- 线程 1 的分配是否保证在被调用
someVariable
之前完成?atomicSet()
- 如果线程 2 以原子方式读取,是否保证
someVariable
在调用之前看到分配?doMoreStuff()
stuffDoneFlag
编辑:
- 我正在使用的原子操作的实现
LOCK
在每个操作中都包含 x86 指令,如果有帮助的话。 - 假设
stuffDoneFlag
以某种方式正确清除。怎么样并不重要。 - 这是一个非常简化的例子。我以这种方式创建它,这样您就不必了解问题的整个背景来回答它。我知道它没有效率。
c++ - 大量文件的原子删除
我试图一次删除 10000 多个文件,例如,要么全部删除,要么全部保留。
当然,显而易见的答案是将所有文件移动到一个临时目录中,并在成功时递归地删除它,但这会使所需的 I/O 量翻倍。
压缩不起作用,因为1)我不知道哪些文件需要删除,2)文件需要经常编辑。
有什么东西可以帮助降低 I/O 成本吗?任何平台都可以。
编辑:让我们假设停电随时可能发生。
multithreading - 您如何实现软件事务内存?
就实际的低级原子指令和内存栅栏(我假设它们已被使用)而言,您如何实现 STM?
对我来说神秘的部分是,给定一些任意代码块,您需要一种方法来返回并确定每个步骤中使用的值是否有效。你如何做到这一点,以及如何有效地做到这一点?这似乎也表明,就像任何其他“锁定”解决方案一样,您希望您的关键部分尽可能小(以减少冲突的可能性),对吗?
此外,STM 是否可以简单地检测“另一个线程在执行计算时进入该区域,因此计算无效”或者它是否可以实际检测是否使用了破坏值(因此幸运的是,有时两个线程可能同时执行相同的关键部分而没有需要回滚)?
c - GCC 新的原子整数运算的替代方案
GCC 最近对原子操作的支持(如此处所述)非常好,是我们需要的 90%。不幸的是,我们的一些产品仍然需要在 Windows 上运行,因此我们也需要在 Windows 上进行原子整数操作。
过去,我们对所有平台都有自定义的汇编语言实现,但我想将所有 *nix 平台转移到 GCC 支持的操作上,我想到也许还有一种更标准的方法来做到这一点现在也在 Windows 上...
在 Windows 上是否有官方认可的方法(除了自己用汇编语言实现它们)?
multithreading - “benaphores”值得在现代操作系统上实施吗?
回到我作为 BeOS 程序员的日子里,我读了 Benoit Schillings 的这篇文章,描述了如何创建一个“Benaphore”:一种使用原子变量来强制执行关键部分的方法,从而避免了在常见的情况下获取/释放互斥锁的需要(无争用)情况。
我认为这相当聪明,而且您似乎可以在任何支持原子增量/减量的平台上执行相同的技巧。
另一方面,这看起来可以很容易地包含在标准互斥锁实现本身中......在这种情况下,在我的程序中实现这个逻辑将是多余的并且不会提供任何好处。
有谁知道现代锁定 API(例如 pthread_mutex_lock()/pthread_mutex_unlock())是否在内部使用这个技巧?如果没有,为什么不呢?
linux - 在 Linux 上保存原子文件而不会丢失元数据
我正在开发一个基于 Perl 的文件同步工具。它将文件下载到一个临时目录(保证与真实文件在同一个文件系统上),然后将临时文件移动到旧文件上,保留权限、所有权和 ACL 等元数据。我想知道如何在 Linux 上实现最后一步。
在 Mac OS X 上,至少在 C 中,我会使用这个exchangedata
函数。这需要两个文件名作为参数并交换它们的内容,使所有元数据(除了 mtime)保持不变。它保证了操作是原子的——所有的读者都可以看到旧文件或新文件,而不会介于两者之间。不幸的是,我认为它在 Linux 上不可用。
我知道它是rename
原子移动的,但它不保留元数据。另一方面,我可以打开文件并用新文件的内容覆盖数据,这将保留所有元数据,但不是原子操作。关于解决这个问题的任何建议?
multithreading - 使用原子交换实现原子增量?
假设我正在为 CPU 编写(汇编)代码,其唯一的原子操作是无条件交换——没有 LL/SC,没有比较和交换,只是简单的交换。(ARM9 就是这种野兽的一个例子。)有没有办法使用交换操作来执行原子递增/递减操作?
有一个相对简单的答案,即使用交换来构建自旋锁,并使用它来提供围绕普通增量和减量的关键部分。但这似乎很笨拙,而且我知道如果 CAS 或 LL/SC 可用,它可以在没有锁的情况下完成。所以我真正想知道的是是否有办法不使用锁来做到这一点。
atomic - Solaris上需要原子加法操作代码(sparc架构)
我需要相当于以下的原子操作代码:
(在 Linux 上添加两个变量 a 和 b 以及存储在 a 和 c 中的输出)
在 Solaris(Sparc 架构)上需要与上述等效。有没有人可以帮帮我?
language-agnostic - 如何构建无锁队列?
我今天花了很多时间研究无锁队列。我有多个生产者,多个消费者的情况。为了测试,我实现了一个在 Win32 下使用 Interlocked SList 的系统,它使我基于重线程任务的代码的性能提高了一倍。但不幸的是,我希望支持多个平台。在多个平台上互锁本身不是问题,我可以放心地假设我可以毫无问题地互锁。然而,实际的实施让我失望了。
最大的问题似乎是您需要保证列表推送/弹出将仅使用一个互锁调用。否则,您将留出空间让另一个线程咬入并将事情搞砸。我不确定微软的实现是如何在幕后工作的,并且很想知道更多。
谁能指出我有用的信息(平台和语言无关紧要)?
除此之外,我很想知道是否可以实现无锁向量。这对我有很大的用处:) 干杯!
编辑:阅读herb 的DDJ 文章后,我可以看到一个减少的锁定队列,与我已经拥有的非常相似。但是我注意到最后有一些论文可以使用双重比较和交换(DCAS)操作进行真正的无锁队列。有没有人使用 cmpxchg8b (或 cmpxchg16b )实现队列?
我现在只是在沉思(还没有阅读论文),但是您可以使用这个系统同时更新头部和尾部指针,从而避免另一个线程在两个原子操作之间跳转的任何问题。但是,您仍然需要获取下一个头指针以针对尾指针进行测试,以查看您是否刚刚修改了尾。当另一个线程准备自己这样做时,如何避免另一个线程更改此信息?这究竟是如何以无锁方式实现的?还是我最好阅读研究论文的不可解读性?;)