我可以使用什么方法使用 genServer 在 Elixir 中创建队列? 主要思想是生成创建长时间运行的流
def handle_call({:create_queue, queue_name}, _from, state) do
create_queue(queue_name)
{:reply, "You have successfully created a queue named #{queue_name}", state}
end
def create_queue(queue_name, list_of_subscribers \\ []) do
spawn fn -> create_queue_thread(list_of_subscribers, queue_name) end
end
我不知道如何仅知道队列的名称来访问队列。我想过返回它的 PID,但我不知道在哪里正确存储它以及之后如何使用它。我想到向所有队列流广播消息,并将其名称与包含其消息的元组进行模式匹配。
我在 gen_tcp 中实现了消息代理,并使用了包含队列名称和队列 pid 映射的超级进程,因此我可以使用发送功能。但是老师对我说“这非常糟糕”,我需要使用 genServer 而不是 gen_tcp 和基本的 Elixir 并发方法来重做我的任务。
def queue_cashier(queuing_process) do
# IO.inspect(queuing_process)
receive do
{ sender, queue_name } ->
{queue_original,_} = Map.pop(queuing_process,queue_name)
# IO.inspect(queuing_process)
if queue_original == nil do
# IO.puts("NIL")
pid = spawn Server, :queue_handler, [%{}]
queuing_process = Map.merge(queuing_process, %{queue_name => pid})
# IO.inspect(queuing_process)
# IO.inspect(pid)
send sender, {pid }
queue_cashier(queuing_process)
else
send sender, {queue_original }
queue_cashier(queuing_process)
end
queue_cashier(queuing_process)
end
queue_cashier(queuing_process)
end
但是老师对我说“这非常糟糕”,我需要重做我的 使用 genServer 而不是 gen_tcp 的任务和基本的 Elixir 并发 方法。
哈哈哈哈!嗯,基本的并发方法是
spawn()
、send()
和 receive
。进程的邮箱实际上是一个 FIFO 实现,因为进程按照接收消息的顺序处理消息,所以只需复制进程邮箱的源代码即可!
我不太确定您的作业的详细信息是什么,但听起来您需要做的第一件事就是实现一个队列。 GenServer 可用于保存值,例如列表。列表的问题在于它本质上是一个 LIFO 实现——因为将东西添加到列表的头部是高效的,这意味着最后添加到列表的东西位于列表的头部,而且它也非常有效。有效地提取列表的头部。队列的一个简单的实现就是将东西存储在 GenServer 状态的列表中,然后当你需要一个值时,在
handle_call(:get_value...)
中你可以反转列表,然后获取反转列表的头,这提供了 FIFO实施。
如果队列需要存储进程,则将pid保存在列表中。