有没有一种方法来实例2个WASM模块,a并且b这样a甚至可以从功能b,也从访问不同的记忆b?例如,让我们说,a通过调用的实现变得内存malloc在b暴露于a。这样,所有有用的内存都来自b. 如果是这样,怎么做?更具体地说,这是否可以在没有额外开销的情况下完成,并且不需要在这些操作之间与 JavaScript 交互(实例化模块和设置导入/导出时的初始化步骤除外)?这种间接和内存访问的性能特征是什么,或者根本没有问题?在这种情况下,我想进行微优化。
(我已经阅读了几篇文档,但我找不到明确的答案。我认为在 Wasm 的未来版本中,有标准化动态链接的计划会有所帮助,但我们还没有。)
我的应用程序从外部源接收数据并将其分组(匹配组项目并将结果显示为 HTML 表格,高达 20k 消息/秒)。
问题是共享内存:应用程序实时工作,我收到带有“创建、更新、删除”标志的消息,因此我将所有内容存储在 RAM 中,不需要任何数据库。但是,当我尝试集群时,某些集群会丢失我的应用程序消息(我尝试使用pm2进行集群)。
因此,现在我尝试使用 WorkerThreads 扩展我的应用程序,但是通过通信parentPort.postMessage/worker.postMessage需要对应用程序进行大量更改。所以现在我尝试通过共享内存SharedArrayBuffer,但我不明白如何在主机和工作人员之间共享对象数组。
const {
Worker, isMainThread, parentPort, workerData
} = require('worker_threads');
if (isMainThread) {
const sab = new SharedArrayBuffer(1024);
sab[0] = {foo: 'bar'};
const worker = new Worker(__filename, {
workerData: sab
});
setInterval(() => {
console.log( sab[0] ); // always {foo: 'bar'}
}, 500);
} else {
let sab = workerData;
sab.foo = false; // changing "foo" value at worker but not in main thread …Run Code Online (Sandbox Code Playgroud) 该函数store_in_shm将 numpy 数组写入共享内存,而第二个函数read_from_shm使用同一共享内存空间中的数据创建 numpy 数组并返回 numpy 数组。
但是,在 Python 3.8 中运行代码会出现以下分段错误:
zsh:分段错误 python foo.py
为什么从函数内部访问numpy数组没有问题read_from_shm,但在函数外部再次访问numpy数组时出现分段错误?
输出:
From read_from_shm(): [0 1 2 3 4 5 6 7 8 9]
zsh: segmentation fault python foo.py
% /Users/athena/opt/anaconda3/envs/test/lib/python3.8/multiprocessing/resource_tracker.py:203: UserWarning: resource_tracker: There appear to be 1 leaked shared_memory objects to clean up at shutdown
warnings.warn('resource_tracker: There appear to be %d '
Run Code Online (Sandbox Code Playgroud)
foo.py
import numpy as np
from multiprocessing import shared_memory
def store_in_shm(data):
shm = shared_memory.SharedMemory(name='foo', create=True, size=data.nbytes)
shmData …Run Code Online (Sandbox Code Playgroud) 在 Python 3.8+ 中,是否可以检查 numpy 数组是否存储在共享内存中?
在以下示例中,sharedArr使用对象的缓冲区创建了一个 numpy 数组multiprocessing.shared_memory.SharedMemory。想知道是否可以写一个函数来检测是否SharedMemory被使用。
import numpy as np
from multiprocessing import shared_memory
if __name__ == '__main__':
# Created numpy array `sharedArr`in shared memory
arr = np.zeros(5)
shm = shared_memory.SharedMemory(create=True, size=arr.nbytes)
sharedArr = np.ndarray(arr.shape, dtype=arr.dtype, buffer=shm.buf)
sharedArr[:] = arr[:]
# How to tell if numpy array is stored in shared memory?
print(type(sharedArr)) # <class 'numpy.ndarray'>
print(hex(id(sharedArr))) # 0x7fac99469f30
shm.close()
shm.unlink()
Run Code Online (Sandbox Code Playgroud) 来自《Effective Java》一书:
虽然 volatile 修饰符不执行互斥,但它保证任何读取该字段的线程都会看到最近写入的值
SO和许多其他来源声称类似的事情。
这是真的?
我的意思是真的,不是一个足够接近的模型,或者只在 x86 上,或者只在 Oracle JVM 中,或者“最近写的”的一些定义,这不是标准的英语解释......
其他来源(SO 示例)说 Java 中的 volatile 就像 C++ 中的获取/释放语义。我认为不提供报价的保证。
我发现在JLS 17.4.4 中它说“对 volatile 变量 v 的写入(第 8.3.1.4 节)与任何线程对 v 的所有后续读取同步(其中“后续”是根据同步顺序定义的)。 ” 但我不太明白。
有很多支持和反对的消息来源,所以我希望答案能够说服其中许多(在任何一方)确实是错误的 - 例如参考或规范,或反示例代码。
我试图让两个进程通过共享内存进行通信。我注意到,如果我使用不同的用户运行它们,第二个用户将在 shm_open() 上失败并拒绝权限,即使它们来自同一组。但是,如果我将执行位添加到模式中,第二个进程在调用 shm_open() 时不会失败。
我想了解这种行为,在 shm_open() 的情况下执行位到底在做什么?特别是,如果在调用 shm_open() 期间设置了执行位,进程可以在 /dev/shm 中执行 shellcode 吗?
手册页是我找到的关于此的最好文档。从 O_CREAT 中的内容来看:
如果共享内存对象不存在,则创建该对象。对象的用户和组所有权取自调用进程的相应有效ID,并且对象的权限位根据模式的低9位设置,除了在进程文件模式创建掩码中设置的那些位(参见 umask(2))为新对象清除
根据我的理解,它从模式中获取权限位(我的 umask 设置为 0002,但更改为 0 似乎不会产生不同的结果)。我在两个程序中都保留了 O_CREAT,因为手册指出“如果共享内存对象不存在,则创建它”,所以我想为两个程序重用相同的代码。
微量元素:
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
int main() {
const char* name = "com/page";
int flags = O_CREAT | O_RDWR;
int mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
int fd = shm_open(name, flags, mode);
if (fd < 1) {
printf("shm_open() failed: %s", strerror(errno)); …Run Code Online (Sandbox Code Playgroud) 我知道有多种技术可以在 python 的进程之间共享内存和数据结构。这个问题专门针对 python 脚本中固有的共享内存,该内存存在于 python 3.6 中,但在 3.10 中似乎不再存在。 有谁知道为什么以及是否可以在 3.10 中恢复此功能?或者说我观察到的这个变化是什么? 我已将 Mac 升级到 Monterey,但它不再支持 python 3.6,因此我被迫升级到 3.9 或 3.10+。
注意:我倾向于在 Mac 上开发并在 Ubuntu 上运行生产。不确定这是否在这里。从历史上看,在 3.6 中,无论操作系统如何,一切行为都相同。
使用以下 python 文件制作一个简单的项目
我的图书馆.py
MyDict = {}
Run Code Online (Sandbox Code Playgroud)
测试.py
import threading
import time
import multiprocessing
import myLibrary
def InitMyDict():
myLibrary.MyDict = {'woot': 1, 'sauce': 2}
print('initialized myLibrary.MyDict to ', myLibrary.MyDict)
def MainLoop():
numOfSubProcessesToStart = 3
for i in range(numOfSubProcessesToStart):
t = threading.Thread(
target=CoolFeature(),
args=())
t.start()
while True:
time.sleep(1)
def CoolFeature():
MyProcess = …Run Code Online (Sandbox Code Playgroud) 保护写访问是否足够,还是有必要保护读访问print-columns?
#!/usr/bin/env raku
my @w_list_items;
len_items_list( <car tree house mouse dog mountain snow roof> );
@w_list_items.say;
sub len_items_list ( @list ) {
my Int $threads = Kernel.cpu-cores;
while $threads > @list.elems {
last if $threads < 2;
$threads = $threads div 2;
}
my Int $size = @list.elems div $threads;
my Array @portions = ( ^$threads ).map: { [ $size * $_, $size * ( $_ + 1 ) ] };
@portions[*-1][1] = @list.elems;
my Promise @promise;
for …Run Code Online (Sandbox Code Playgroud) 我正在尝试为我的 Python 应用程序创建一个共享内存,该内存应该在父进程以及从该父进程生成的另一个进程中使用。在大多数情况下,工作正常,但是,有时我会得到以下堆栈跟踪:
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/usr/lib/python3.8/multiprocessing/spawn.py", line 116, in spawn_main
exitcode = _main(fd, parent_sentinel)
File "/usr/lib/python3.8/multiprocessing/spawn.py", line 126, in _main
self = reduction.pickle.load(from_parent)
File "/usr/lib/python3.8/multiprocessing/synchronize.py", line 110, in __setstate__
self._semlock = _multiprocessing.SemLock._rebuild(*state)
FileNotFoundError: [Errno 2] No such file or directory: '/psm_47f7f5d7'
Run Code Online (Sandbox Code Playgroud)
我想强调的是,我们的代码/应用程序在 99% 的情况下都可以正常工作。我们在应用程序中定期为每个此类进程生成新的共享内存(这是一个服务器进程,因此它每天 24/7 运行)。几乎所有时候这都工作正常,只是偶尔会抛出上面的错误,然后杀死整个应用程序。
更新:我注意到这个问题主要发生在应用程序已经运行了一段时间的时候。当我启动它时,共享内存的创建和生成新进程工作正常,没有此错误。
共享内存是这样创建的:
# Spawn context for multiprocessing
_mp_spawn_ctxt = multiprocessing.get_context("spawn")
_mp_spawn_ctxt_pipe = _mp_spawn_ctxt.Pipe
# Create shared memory
mem_size = width * height * …Run Code Online (Sandbox Code Playgroud) python linux shared-memory multiprocessing python-multiprocessing
我在两个进程之间分配了很大的共享内存(4 MB)。我的 process-1 在此内存池上进行写入,将其用作循环缓冲区,通过逐个写入 256 字节的块。我的 process-2 从内存中读取。我正在使用锁进行同步。我正在测量写入时间,每执行 16 次操作就会出现峰值。我的猜测是,这是因为访问新页面(因为 16*256 字节 = 4096 字节)。
由于这种情况发生在程序的关键点并导致高延迟,因此我决定在构造函数分配/绑定到共享内存后通过访问此内存池来预热 process-1 的页表。
//global var
dummy_byte = 0;
for (int i=0; i<16*1024; i++)
{
dummy_byte ^= buffer[i*256];
}
Run Code Online (Sandbox Code Playgroud)
目标是访问每个块中的一个字节,以便获取所有页面。我为此使用全局变量,否则编译器会优化并删除我的循环(因为没有人读取保存的值)。我后来使用 objdump 验证了这段代码没有被删除。
我面临的问题是延迟峰值仍在发生。在玩预热逻辑时,我尝试了以下方法:
for (int i=0; i<16*1024; i++)
{
buffer[i*256] = 0;
}
Run Code Online (Sandbox Code Playgroud)
我发现这不会导致临界点出现延迟峰值。问题是我不想将垃圾写入缓冲区,因为那里可能存在一些有用的东西,并且对同一字节进行读写会导致竞争条件,因为另一个进程可能正在从共享内存中读取。
我想知道:
shared-memory ×10
python ×4
c++ ×2
linux ×2
numpy ×2
python-3.x ×2
caching ×1
concurrency ×1
java ×1
macos ×1
memory ×1
node.js ×1
paging ×1
python-3.8 ×1
raku ×1
sysv ×1
volatile ×1
webassembly ×1
worker ×1