簡體   English   中英

可以使用跨語言平台的 System V 共享內存在 4 字節 int 上實現無鎖原子寫/一致讀操作嗎?

[英]Can a lock-free atomic write / consistent read operation be achieved on a 4 byte int using System V shared memory across language platforms?

我想在 System V 共享內存中實現一個無鎖counter ,一個 4 字節的int 作者是一個C++程序,讀者是一個Python程序。 工作大致是這樣的:

  • C++ 代碼在原子操作中更新counter
  • Python代碼讀取counter並具有一致的內存視圖(最終一致性完全可以接受)
  • 沒有實施鎖來實現這一點

在 C++ 語言中,有原子獲取/更新操作可以實現這一點並保證內存一致性,我相信在 Python 中也是如此。

然而,據我所知,C++ 中關於原子操作的假設不一定適用於用另一種語言和編譯器編寫和編譯的代碼。

有沒有一種方法可以在不涉及實現低級鎖的情況下實現跨語言的共享內存的一致視圖?

有沒有一種方法可以在不涉及實現低級鎖的情況下實現跨語言的共享內存的一致視圖?

不,不是一般的。

首先,我想說這與語言無關,而更多地與實際平台、架構、實現或操作系統有關。

因為語言差異很大,以 Python 為例:它沒有直接訪問內存的語言本機方式,或者以低級方式說。 然而,它的一些實現確實提供了自己的 API。 用於這種低級使用的語言對此具有抽象,就像 C、C++ 或 Rust 一樣。 但是這些抽象的實現方式通常完全不同,因為它們通常取決於代碼的運行、解釋或編譯位置。 某些架構的整數是大端,在大多數情況下,如 x86 或 arm,它的小端。 操作系統也有發言權,例如內存被使用和抽象。

雖然許多語言都有一個共同的線性內存抽象,但它在原子方面變得更加混亂:C++ 的編譯器可以生成機器代碼,即檢查 CPU 運行的程序集是否支持新的花哨的原子整數指令並使用它們或回退通常支持原子標志加上整數。 如果代碼可以在操作系統管理的環境中運行,它可以只依賴於操作系統、自旋鎖或由 POSIX、SystemV、Linux、Windows 定義的標准化 API。

對於非命令式語言,它變得更加混亂。

因此,為了在語言之間交換數據,這些語言的實現必須使用一些公共交換。 例如,他們可以嘗試直接通過共享內存來做到這一點。 這被稱為應用程序二進制接口 (ABI),因為內存抽象至少對它們先驗是通用的。 或者操作系統或架構甚至可能對這些東西進行標准化,甚至支持 API。

System V 將是為這種交換而設計的 API,但由於 AFAIK 它沒有原子的抽象或鎖定較少的抽象,因此即使 System V 上下文不在標題中,答案仍然是否定的。

我將對 Superlokkus 的一些斷言提出異議。

mmap原語在 C++ 和 Python 中都可用。 該原語為您提供位於兩個進程共享的物理頁面中的內存。 不同的虛擬地址,相同的內存物理頁。 另一個進程可以立即查看一個進程的更改。 這就是它必須工作的方式。 它在硬件級別運行。 抽象是無關緊要的。

現在,這並不意味着您可以獲得這些更改的通知。 如果您在循環中輪詢(大概是在檢查之間休眠的友好循環),那么您將在下次檢查時看到更改。

是的,使用atomics庫以及合適的共享內存庫(例如mmapshared_memory )。
此示例假設您的原子整數位於共享內存段的前 4 個字節中。

from atomics import atomicview, MemoryOrder, INT
from multiprocessing import shared_memory


# connect to existing shared memory segment
shmem = SharedMemory(name="test_shmem")

# get buf corresponding to "atomic" region
buf = shmem.buf[:4]

# atomically read from buffer
with atomicview(buffer=buf, atype=INT) as a:
    value = a.load(order=MemoryOrder.ACQUIRE)

# print our value
print(value)

# del our buf object (or shmem.close() will complain)
del buf

# close our shared memory handle
shmem.close()

我們可以在這里使用ACQUIRE內存順序而不是默認的SEQ_CST

atomicview只能通過with語句創建和使用,因此您需要手動保留buf (並正確管理其生命周期)。

注意:我是這個庫的作者

暫無
暫無

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

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