簡體   English   中英

F#同時在多個線程中更新列表

[英]F# update list in multiple threads at same time

我是F#的新手,所以也許解決方案對某人來說很清楚,但我找不到它。
想象一下世界大塊的游戲世界(類似於Minecraft),但對於更多的玩家。
理論上,像C ++,java或C#這樣的語言可以同時修改多個世界的塊。 兩個或更多玩家嘗試在不同的塊中放置或移除塊,並且所有這些動作可以改變世界的狀態而不會相互影響,只要每個塊中發生的動作不超過一個。 序列化僅在一個塊中的多個玩家執行修改時發生。

我對F#的理解是我需要在全局范圍內序列化這些動作,並且在整個世界中不能同時發生兩個動作,因為更新功能需要actual world state update params(like add/remove blok)並返回new world state
對於該示例, world state包含chunk list

有沒有辦法並行進行世界更新?
world state可以以不同方式存儲以允許同時更新多個塊?

聽起來你需要確保每個塊一次運行一個動作。 您可以通過將它們存儲在郵箱處理器(通常稱為“代理”)中來保護狀態。 您可以從多個線程向代理發送多條消息。 它們將一次排隊並處理一個。

這里有詳細的討論: https//fsharpforfunandprofit.com/posts/concurrency-actor-model/

首先,我不會在前面的答案中添加任何技術細節,所以如果你喜歡他們的解決方案,你應該繼續並將其標記為答案。 但是,我希望這會給出一些額外的背景......

問題的根本問題在於,為了做出有關修改塊的決定,您需要多大程度地保持您的世界狀態。

考慮一個我有兩個塊的世界,讓我們稱它們為A和B.考慮我想在塊A中添加或刪除塊的用例。所有重要的問題是:

  • 我是否需要了解塊B中的塊以進行驗證,然后從塊A中執行塊的添加/刪除。

例如,如果我的世界中只有有限數量的塊,我可能需要這些信息來驗證我實際上可以添加一個塊而不會超出我的限制。 這里的關鍵是我的“一致性邊界”是我的整個世界 - 為了向大塊AI添加新塊需要關於我世界中每個標志的一致信息。 如果我的決定中途另一個線程跳入並向塊B添加一個塊是沒有好處的。 如果這是一個要求那么你沒有選擇 - 即使在C#/ C ++情況下 - 你需要鎖定對你的世界的訪問所以在任何時候都只能執行一次這樣的動作。

從你說出問題的方式來看,我懷疑情況並非如此。 在這種情況下,我們需要准確檢查您的一致性要求。 一個較弱的要求是,如果我將塊添加到塊A,我至少必須有關於塊A中塊的數量(和位置)的一致信息。在C#/ C ++情況下,這將意味着必須放置鎖定訪問個人“塊數據”,但不是整個世界。

在F#中對此進行建模的簡單方法是(使用此答案中的建議):

open FSharp.Core

type ChunkMessage = 
    AddBlock
    | RemoveBlock

type MyWorld = 
    {
        Blocks : List<MailboxProcessor<ChunkMessage>>
    }

請注意, MyWorld是一個可變的,但每個MailboxProcessor封裝了一個狀態,該狀態只能通過一次處理一條消息來改變。

Blocks的實現不一定是MailboxProcessor的列表,你可以使用線程安全方法的線程安全集合,但是如Quick Brown Fox建議的那樣使用它們導致一個特別好的編程模型。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM