我一直渴望得到一个STLish容器,我可以放入共享内存段或内存映射文件中.
我已经考虑使用自定义分配器和placement new将常规STL容器放入共享内存段.(像这篇ddj 文章).问题是STL容器内部会有指向他们拥有的内存的指针.因此,如果共享内存段或内存映射文件加载到不同的基址(可能在后续运行或第二个进程中),则内部指针突然无效.据我所知,自定义分配器方法只有在您始终可以将内存段映射到同一地址的进程时才有效.至少对于内存映射文件,我有很多经验,如果你只是让系统将它映射到感觉就好的地方.
我对如何做到这一点有一些想法,但如果其他人已经完成了这项工作,那我就想避免它(那就是我,懒惰).
我目前正在退出讨论,因为最好的锁定策略是高度依赖于应用程序的.
我有一些在服务器上运行的C++服务和一个监听特定端口的节点服务器程序.我可以在C++服务和nodejs程序之间使用共享内存吗?我希望用户通过nodejs服务器发送数据,那些C++服务访问它们.可能吗?
我正在用C++编写分布式应用程序框架.其中一个要求是提供分布式共享内存.我不是从头开始写自己的(并且可能重新发明轮子),我想我会看看是否有任何预先存在的开源库 - 快速谷歌搜索没有产生任何有用的东西.
这里有没有人有他们可以推荐的优秀C++ DSM库的经验?
理想情况下,该库将支持MRMW(多个读取器/多个写入器),但如果需要,我可以使用MRSW(多个读取器,单个写入器).我在Linux上开发.
我用WinAPI的MapViewOfFile功能遇到了这种情况.互联网搜索没有发现任何明显的修复,所以我将在这里分享我的问题和解决方案.
请考虑以下代码段:
const char *name = "Global\\Object_Name";
unsigned long size = get_object_size();
HANDLE handle = CreateFileMapping(INVALID_HANDLE_VALUE,
NULL,
PAGE_READWRITE,
0,
size,
name);
if (!handle || handle == INVALID_HANDLE_VALUE)
exit(GetLastError());
bool created = GetLastError() == 0;
void *block = MapViewOfFile( handle,
FILE_MAP_ALL_ACCESS,
0,
0,
size);
if (block == NULL)
exit(GetLastError());
Run Code Online (Sandbox Code Playgroud)
在一个特定情况下,CreateFileMapping成功返回一个句柄.GetLastError回来了ERROR_ALREADY_EXISTS,所以created == false.现在,MapViewOfFile使用与我传递给的相同大小的调用CreateFileMapping返回NULL并GetLastError返回0x05:ERROR_ACCESS_DENIED.该进程以管理员权限运行.
MSDN文档没有真正提到出现这种情况的任何原因.那么为什么CreateFileMapping成功,但MapViewOfFile失败了?
通过浏览shmget()的手册页,我知道shmget()调用会在内存中分配页面,这些页面可以跨进程共享.
是否要创建内核内存页面,该页面映射到进程的本地地址空间?或者它是为该段保留的相同进程内存页面,同样也将为其他附加进程共享?
我的假设:当调用shmget()时,内核将保留段数/页面数.调用shmat()时,保留的段将映射到进程的地址空间/页面.当新进程附加到同一段时,先前创建的内核segemnt将映射到新进程地址空间.
它是否正确 ?
我编写了一个连续运行的服务器(GNU C++/Linux),偶尔执行小型独立程序来完成工作.为了有效地将数据提供给工作程序,服务器创建并映射共享内存对象(为清楚起见,代码缩写):
int fd = shm_open("/shm_file", O_CREAT | O_TRUNC | O_RDWR, S_IRUSR | S_IWUSR);
ftruncate(...);
data = mmap(...);
// etc...
launchWorker(...); // Start the worker program
Run Code Online (Sandbox Code Playgroud)
然后,worker程序以类似的方式打开这个共享内存(除了只读,没有O_CREAT和O_TRUNC,即我们假设它已经存在).
当worker完成时,它会关闭文件描述符,使用munmap(...)取消映射并使用shm_unlink(...)取消链接.
此时,有一个文件"/ dev/shm/shm_file",我猜是共享内存对象.在工作器中取消链接不会删除它,因为服务器仍然打开它.当服务器取消链接时,文件系统对象消失.此行为与shm_open/shm_unlink的手册页一致,并且适用于我的服务器/工作人员案例.
但是,现在我希望工作人员能够在他们之间共享某些数据,并且可能(用于测试)在服务器未运行时执行此操作.
如果我在一个工作程序中创建一个共享内存对象,并且在退出时不要使用munmap(...)和shm_unlink(...),我注意到共享内存对象保留在/ dev/shm中,我可以打开它又在另一个工人计划中.这很方便.
但是,这样做是否安全?(即重复运行映射共享内存的程序,然后不取消映射/取消链接)?我猜测unmap()并不重要,因为内存映射会随着进程消失,但是shm_unlink呢?鉴于操作系统决定何时根据对象是否仍在使用来删除对象,如果我每次都无法调用shm_unlink(),这会导致某种泄漏吗?
接受C风格数组作为参数的最佳方法是什么,将其修改为D风格的数组(包括更改长度),并将其作为C风格的数组返回?
我在D中编写一个库,它编译成带有C接口的DLL(我将从C++调用我的D DLL,因此需要C接口).
它需要byte数组并修改它们的内容,有时会改变数组长度.
因为我使用的是C接口,所以我的函数必须接受C风格的数组.理想情况下,bufferMaxSize如果给定的缓冲区太小,我希望能够分配更多的内存(即扩展).
这就是我的D DLL现在接受参数的方式:
// D library code; compiles to DLL with C interface.
// bufferSize is the data length, and is a pointer because I may modify the data length.
// bufferMaxSize is the total allocated buffer size.
export extern(C) void patchData(const size_t bufferMaxSize, size_t * bufferSize, byte * buffer) { ... }
Run Code Online (Sandbox Code Playgroud)
在我的D库中,我有现有的代码,可以接受D风格的数组.沿着这条线的某个地方,必须将C风格的数组转换为D风格的数组.
我正在进行这样的转换(简化示例):
// D library code; compiles to DLL with …Run Code Online (Sandbox Code Playgroud) 我正在尝试将程序代码放入并执行到共享内存区域.初始化和分配共享内存以及将shellcode复制到"新"内存按预期工作,但是一旦我尝试执行它,它就不起作用.有谁知道问题可能是什么?
我想那write(1, 0x6000d8, 13) = -1 EFAULT (Bad address)可能是错误?可能是什么导致了这个?
我包含了代码和stract错误输出.C代码基于Adam Rosenfield在本期杂志中的回答.
C代码
#include <string.h>
#include <sys/mman.h>
// My own shellcode, obtained through objdump
// works on its own (a hello world-program)
const char shellcode[] = "\xb8\x01\x00\x00\x00\xbf\x01\x00\x00\x00\x48\xbe\xd8\x00\x60\x00\x00\x00\x00\x00\xba\x0d\x00\x00\x00\x0f\x05\xb8\x3c\x00\x00\x00\xbf\x00\x00\x00\x00\x0f\x05";
int main(int argc, char **argv)
{
void *mem = mmap(0, sizeof(shellcode), PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);
memcpy(mem, shellcode, sizeof(shellcode));
mprotect(mem, sizeof(shellcode), PROT_READ|PROT_WRITE|PROT_EXEC);
int (*func)();
func = (int (*)())mem;
(int)(*func)();
munmap(mem, sizeof(shellcode));
return 0;
}
Run Code Online (Sandbox Code Playgroud)
Strace日志
execve("./memory", ["./memory"], [/* 17 …Run Code Online (Sandbox Code Playgroud) 嘿我正在尝试在两个进程之间创建一个共享对象.并尝试读取和更改每个进程中的值.这是我的简单结构.
编辑:我在我的结构中添加了一个构造函数.
struct shared{
shared(){
value = 10;
name = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
}
int value;
string name;
};
Run Code Online (Sandbox Code Playgroud)
我试过在调用fork()之前和之后调用shmat()但是没有任何改变它仍然给出了分段错误.
编辑:并在shmat()后添加一个检查,看看它是否失败.
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <iostream>
#include <sys/shm.h>
#include <string.h>
using namespace std;
struct shared{
shared(){
value = 10;
name = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
}
int value;
string name;
};
int main(){
int shm_id = shmget(IPC_PRIVATE,sizeof(shared),0);
if(shm_id == -1){
cout<<"shmget() failed "<<endl;
return -1;
}
pid_t pid = fork();
if(pid == -1){
cout<<"fork() failed "<<endl;
return -2;
}
shared* sharedPtr = …Run Code Online (Sandbox Code Playgroud) 我正在改进一个解析XML并对其子树进行分类和索引的程序.实际程序太大而无法显示在这里,所以我把它归结为一个最小的测试用例,显示我遇到的问题.
这个想法是:
alpino_ds并行处理文件中的所有节点请注意,在实际代码中还有一些注意事项:
dicts of four levels deep consisting of dicts, sets, ints, and strings, as well as dict-to-filehandle, and Counter() objects;ThreadPoolExecutor) and even though there was some gain (I calculated around 5% improvement in speed), this …python parallel-processing shared-memory python-3.x python-multiprocessing