问题标签 [lifo]
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.
c - 如何防止使用原子比较和交换实现的并发 lifo 堆栈中的损坏
下面是一个简化的 C 程序,它演示了我在使用 GNU 内置比较和交换在英特尔 cpu 上实现的并发堆栈时遇到的问题。我花了一段时间才明白发生了什么,但现在我明白了,它完全在原子比较和交换提供的保证范围内。
当一个节点从堆栈中弹出,修改,然后放回堆栈时,修改后的值可能成为堆栈的新头部,从而破坏它。test_get 中的注释描述了导致这种情况的事件顺序。
有没有办法多次可靠地使用具有相同堆栈的相同节点?这是一个夸张的例子,但即使将未修改的节点返回给 gHead 也可能泄漏其他节点。这种数据结构的初衷是重复使用相同的节点。
我正在使用 8 个逻辑核心运行此测试。当我只使用 4 个线程时,问题很少发生,但使用 8 个线程很容易重现。我有一台配备 Intel Core i7 的 MacBook。
我对使用一些解决了这个问题的库或框架不感兴趣,我想知道它是如何解决的。谢谢你。
编辑:
这里有两个在我的情况下不起作用的解决方案。
一些体系结构提供了 ll/sc 指令对,它们对地址而不是值执行原子测试。对该地址的任何写入,即使是相同的值,也会阻止成功。
一些架构提供大于指针大小的比较和交换。有了这个,单调计数器与指针配对,每次使用时都会以原子方式递增,因此值总是会变化。一些英特尔芯片支持这一点,但没有 GNU 包装器。
这是一个问题。两个线程,A 和 B,到达test_get
它们具有相同值的点,result
而不是NULL
。然后发生以下顺序:
- 线程 A 通过比较和交换并
result
从test_get
- 线程A修改内容
result
- 线程 B 取消引用
result
,得到任何线程 A 放在那里 - 线程 A 结束
result
并调用test_put
- 线程 A 通过比较和交换
test_put
将结果放回gHead
- 线程 B 到达比较并换入
test_get
并通过 - 线程 B 现在已经被
gHead
线程 A 的值破坏了
这是一个类似的场景,其中三个线程不需要线程 A 进行修改result
。
- 线程 A 通过比较和交换并
result
从test_get
- 线程A不修改内容
result
- 线程 B 取消引用
result
,在scratch
- 线程 C 调用
test_put
不相关的值并成功 - 线程A调用
test_put
并成功result
放回gHead
- 线程 B 到达比较并换入
test_get
并通过 - 线程 B 现在已
gHead
通过泄漏任何线程 C 添加的内容而损坏
在任何一种情况下,问题都是线程 A 通过了比较和交换两次,一次是 get,然后是 put,在线程 B 到达比较和交换以获得 get 之前。线程 B 的任何从头开始的值都应该被丢弃,但这并不是因为 gHead 中的值看起来是正确的。
任何使这种可能性降低而不实际阻止它的解决方案只会使错误更难追踪。
请注意,临时变量只是在原子指令开始之前放置结果的取消引用值的位置的名称。删除名称确实会删除可能被中断的取消引用和比较之间的时间片。
另请注意,原子意味着它作为一个整体成功或失败。指针的任何对齐读取在相关硬件上都是隐式原子的。就其他线程而言,不存在只读取一半指针的可中断点。
java - 信号量或锁定,等待列表以 LIFO 顺序提供服务
使用 LIFO 有序的等待线程列表寻找有效的信号量或锁,以尝试在以下实现中尽量减少缓存和页面缺失FixedThreadPoolExecutor
。
javascript - RegEx - 匹配事件的 LIFO 缓冲区
如何通过在 Javascript 中使用正则表达式在匹配事件上创建 LIFO 缓冲区?
这是一个例子:
输入:
输出应该是:
python - Python:先进先出打印
我是 python 的初学者,我遇到了这个程序的问题:
下面的程序是后进先出 (LIFO)。我想让它成为先进先出 (FIFO) 程序。
这是节点列表:
注意:“Rainbow”应该在“Arc”的底部或在 FIFO 中(下图是 LIFO)
我正在考虑在 NodeList 中放置一个新的定义,例如 setPrevious 但我不知道如何。(老实说,我对这些 self.head = none 东西真的很陌生。我曾经写过 self.items = [])
任何帮助和提示将不胜感激!谢谢!
assembly - 基于 Intel 的汇编语言。堆栈输出
所以目前我的输出是:
面积:17 | 点数:1 | 概率:64 / 134519798
什么时候应该:
面积:1 | 点数:17 | 概率:1 / 64
压入堆栈的值从第一个到最后一个:
64
1
17
1
所以首先应该是 1,然后是 17...1....64。似乎第一个 1 被忽略了,所以我试图研究它,看看我能找到什么,但我做不到。我已经验证了我推入堆栈的变量有一个值。
任何帮助,将不胜感激。
asynchronous - 使用 LIFO 逻辑操作的 MailboxProcessor
我正在学习 F# 代理 ( MailboxProcessor
)。
我正在处理一个非常规的问题。
- 我有一个代理 (
dataSource
),它是流数据的来源。数据必须由一组代理 (dataProcessor
) 处理。我们可以将dataProcessor
其视为某种跟踪设备。 - 数据流入的速度
dataProcessor
可能比处理其输入的速度要快。 - 有一些延迟是可以的。但是,我必须确保代理始终专注于其工作,并且不会因过时的观察结果而堆积如山
我正在探索解决这个问题的方法。
第一个想法是在. 当可用于接收和处理数据时,将发送可用的最新观察结果。此解决方案可能有效,但可能会变得复杂,因为可能需要阻止并重新激活;并将其状态传达给,从而导致双向通信问题。这个问题可能归结为消费者-生产者问题,但我不确定..dataSource
dataSource
dataProcessor
dataProcessor
dataSource
blocking queue
第二个想法是 dataProcessor
处理消息排序。在这种架构中,将简单地在's 队列dataSource
中发布更新。将用于获取其队列中可用的最新数据。这可能是要走的路。但是,我不确定在当前设计中是否可以清除消息队列,删除旧的过时消息。此外,这里写道:dataProcessor
dataProcessor
Scan
MailboxProcessor
不幸的是,当前版本的 F# 中的 TryScan 函数在两个方面被破坏了。首先,重点是指定超时,但实现实际上并没有兑现它。具体来说,不相关的消息会重置计时器。其次,与其他 Scan 函数一样,消息队列在锁定下进行检查,该锁定防止任何其他线程在扫描期间发布消息,这可以是任意长的时间。因此,TryScan 函数本身往往会锁定并发系统,甚至会引入死锁,因为调用者的代码是在锁内评估的(例如,当锁下的代码阻塞等待时,从函数参数发布到 Scan 或 TryScan 可能会使代理死锁获取它已经处于的锁)。
让最新的观察结果反弹可能是个问题。这篇文章的作者@Jon Harrop 建议
我设法围绕它进行架构设计,最终的架构实际上更好。本质上,我急切地
Receive
使用我自己的本地队列来过滤所有消息和过滤器。
这个想法当然值得探索,但在开始使用代码之前,我会欢迎一些关于如何构建我的解决方案的意见。
谢谢你。
python - 仅使用 python 中的第一个参数插入优先级队列
如何将项目插入优先级队列,但确保它只将给定的第一个参数作为优先级。例如:
我希望将前两个 if 语句放入priorityQueue
LIFO。我该怎么做?
vhdl - LIFO内存vhdl代码理解
我有这个用于 lifo 内存的代码,但我不明白为什么在第 27 行 (if(last = n-2) then full <= '1'; end if;)最后一个信号不等于 n-1。如果有人可以向我解释,我将不胜感激。
java - 是否有准备好使用 Java lifo 类(堆栈)并在重新插入时将其推到前面?
我正在寻找具有唯一值的 Java LIFO 结构。此外,它应该在重新插入时将已经插入的值提升到前面。例如,跟踪聚焦窗口的顺序会很有用。
Stack
我知道通过扩展或使用or来实现并不难LinkedHashSet
,但也许我错过了标准 Java 类中已经存在的实现。
c++ - 比较堆栈的双打导致总是相等
我正在尝试比较两个堆栈,看看它们是否相等。不幸的是,这段代码使得我所有的比较都说堆栈是相等的,即使堆栈不是。
Stack_implementation.cpp
片段:
main.cpp
相关片段:
输出总是
stack1 = stack2
有谁知道怎么了?