我正在寻找一种满足以下属性的队列算法:
这是一个关于合适算法的一般问题,因为我想在几个不同的场景中使用它。但是为了帮助可视化需求,下面是一个用例示例:
如果用户而不是页面打开了多个producer-tabs,则这些选项卡没有彼此可用的引用,因此通常的通信方法(postMessage或直接调用其他选项卡的JS代码) ) 出局。他们之间仍可以相互沟通的方式之一是LocalStorage,如下所示:Javascript; communication between tabs/windows with same origin。但是LocalStorage不是线程安全的#34;详细here。
注意:可能还有其他方法可以在浏览器中实现交叉标签通信(Flash,...),但这些不这个问题的目的是因为他们不会转换为我的其他用例。这实际上只是我想要找到的一般队列算法的一个示例用例。
更多参数:
更新
Two-Lock Concurrent Queue Algorithm by Michael and Scott看起来可行,但我需要两件事来实现它:
更新2:
看来,我对这本字典还不够具体:
它只不过是一个微不足道的键值存储。它提供了函数get(key)
来读取键的值,put(key, value)
来更改键的值,delete(key)
来删除键。在我的一些用例中,我也可以迭代密钥,但如果可能的话,我希望避免它的普遍性。密钥是任意的,生产者和消费者可以根据需要创建或计算它们。该词典不提供任何自动生成唯一键的工具。
示例包括HTML LocalStorage,Google AppEngine的数据存储区,Java Map,Python字典,甚至只包含单个目录的文件系统(其中键是文件名,值是内容的值)的文件)。
答案 0 :(得分:0)
只需使用RDBMS即可。在MS SQL中非常简单,对于PostgresSQL,您必须使用RETURNING关键字,对于MySQL,您可能必须使用触发器。
CREATE TABLE Q ([Key] BIGINT IDENTITY(1,1) PRIMARY KEY, [Message] NVARCHAR(4000))
INSERT INTO Q OUTPUT inserted.* VALUE(@message)
DELETE TOP(1) Q WITH (READPAST) OUTPUT deleted.*
如果您真的希望使用算法解决方案,只需使用环形缓冲区。
const int MAX_Q_SIZE = 20000000;
static string[] Q = new string[MAX_Q_SIZE];
static long ProducerID = 0;
static long ConsumerID = 0;
public static long Produce(string message) {
long key = Interlocked.Increment(ref ProducerID);
int idx = (int)(key % MAX_Q_SIZE);
Q[idx] = message;
return key;
}
public static string Consume() {
long key = Interlocked.Increment(ref ConsumerID);
int idx = (int)(key % MAX_Q_SIZE);
string message = Q[idx];
return message;
}