我目前尝试使用Windows CreateFileMapping机制实现一些进程间通信.我知道我需要首先使用CreateFileMapping创建文件映射对象,然后使用MapViewOfFile创建指向实际数据的指针.然后,该示例使用CopyMemory将数据放入mapfile.
在我的应用程序中,我有一个图像缓冲区(1 MB大),我想发送到另一个进程.所以现在我查询指向图像的指针,然后将整个图像缓冲区复制到mapfile中.但我想知道这是否真的有必要.是不是可以只在共享内存中复制指向图像缓冲区数据的实际指针?我尝试了一下但没有成功.
我正在尝试解决MPI_Irecv中的致命错误:中止作业并收到对该查询的混合(有用但不完整)响应.
该错误消息是以下内容:
aborting job:
> Fatal error in MPI_Irecv: Other MPI
> error, error stack: MPI_Irecv(143):
> MPI_Irecv(buf=0x8294a60, count=48,
> MPI_DOUBLE, src=2, tag=-1,
> MPI_COMM_WORLD, request=0xffffd6ac)
> failed MPID_Irecv(64): Out of
> memory
Run Code Online (Sandbox Code Playgroud)
我正在寻求某人的帮助来回答这些问题(我需要指导以帮助调试和解决此死锁)
在"MPI非阻塞发送和接收"结束时,发送/接收完成后是自己释放的内存还是必须强制释放它?
如果我使用"多核心"而不是单核心,会解决"内存不足"的问题吗?我们目前有4个处理器到1个核心,我使用以下命令提交我的工作:mpirun -np 4.我尝试使用mpirun n -4但它仍然在同一个核心上运行了4个线程.
我如何计算出我的程序需要多少"共享内存"?
MPI_ISend/MPI_IRecv在我的代码中的递归循环内部,因此如果错误源位于那里则不太清楚(如果我只使用一次或两次发送/接收命令,系统计算就好了没有"内存不足问题"如果是这样,如何检查和减轻此类信息?
#include <mpi.h>
#define Rows 48
double *A = new double[Rows];
double *AA = new double[Rows];
....
....
int main (int argc, char *argv[])
{
MPI_Status status[8];
MPI_Request request[8];
MPI_Init (&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &p);
MPI_Comm_rank(MPI_COMM_WORLD, …Run Code Online (Sandbox Code Playgroud) 我已经实现了一个简单的共享记忆代码,它分散在两个进程中(1个用作编写器,其他用作读取器).但是我想管理这个SHM代码(就像内存管理器一样),它独立于任何读写器进程.通过简单地给出一些钩子/指针,任何人都可以建议我这样做.或相关信息的任何相关代码或链接?还有一个我可以使用Zygote流程来实现它吗?
我需要一些帮助来理解Ron Farber代码的行为:http://www.drdobbs.com/parallel/cuda-supercomputing-for-the-masses-part/208801731? pgno = 2
我不明白共享内存的使用如何在非共享内存版本上提供更快的性能.即如果我添加一些索引计算步骤并使用添加另一个Rd/Wr循环来访问共享内存,这怎么能比单独使用全局内存更快?在任何一种情况下,相同的数字或Rd/Wr循环访问全局mem.每个内核实例只能访问一次数据.数据仍然使用全局内存进/出.内核实例的数量是相同的.寄存器计数看起来是一样的.如何添加更多处理步骤使其更快.(我们不会减去任何流程步骤.)基本上我们正在做更多的工作,而且它的工作更快.
共享内存访问速度比全局快得多,但它不是零(或负数).我错过了什么?
'慢'代码:
__global__ void reverseArrayBlock(int *d_out, int *d_in) {
int inOffset = blockDim.x * blockIdx.x;
int outOffset = blockDim.x * (gridDim.x - 1 - blockIdx.x);
int in = inOffset + threadIdx.x;
int out = outOffset + (blockDim.x - 1 - threadIdx.x);
d_out[out] = d_in[in];
}
Run Code Online (Sandbox Code Playgroud)
"快速"代码:
__global__ void reverseArrayBlock(int *d_out, int *d_in) {
extern __shared__ int s_data[];
int inOffset = blockDim.x * blockIdx.x;
int in = inOffset + threadIdx.x;
// Load …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用CreateFileMapping和OpenFileMapping在进程之间共享内存.这不是我想要的 - OpenFileMapping返回null而GetLastError是5 - 访问被拒绝.我有什么想法我做错了吗?名称就像MemoryTest.
编辑:
使用CreateFileMapping两次我都可以读取在其他进程中写入的数据.这是一个问题的原因是我得到错误183 - 内存区已经存在.但是,它仍然返回现有内存的句柄.
var map_handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(int), name.c_str());
....
var handle = MapViewOfFile(map_handle, FILE_MAP_ALL_ACCESS , 0, 0, 0)
*handle = 10;
UnMapViewOfFile(map_handle);
getchar();
Run Code Online (Sandbox Code Playgroud)
其他过程:
var map_handle = OpenFileMapping(PAGE_READWRITE, false, name.c_str())
....
var handle = MapViewOfFile(map_handle, FILE_MAP_ALL_ACCESS , 0, 0, 0) //returns null
var out = *handle;
getchar();
Run Code Online (Sandbox Code Playgroud)
这适用于第二个过程:
var map_handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(int), name.c_str());
....
var handle = MapViewOfFile(map_handle, FILE_MAP_ALL_ACCESS , 0, 0, 0) //returns null
var …Run Code Online (Sandbox Code Playgroud) 我在C linux中使用共享内存实现IPC.这是我的接收过程.它收到正确的长度但不是消息.但是发送过程正确地发送它.请看这个,让我知道错误.
//header files
#include "/home/user/msgbuf.h"
#define SHMSZ 127
int main()
{
int shmid;
key_t key;
message_buf *rbuf;
rbuf=malloc(sizeof(*rbuf));
key = ftok("/home/user/shmem",17);
if ((shmid = shmget(key, SHMSZ, 0666)) < 0)
{ perror("shmget");
exit(1);
}
printf("\nShared Memory Id = %d\n",shmid);
if ((rbuf = shmat(shmid, NULL, 0)) == (message_buf *) -1)
{ perror("shmat");
exit(1);
}
printf("\nMEMORY SEGMENT ATTACHED TO THE CLIENT'S PROCESS\n");
/* Now read what the server put in the memory */
printf("\nmsglen = %d",rbuf->msglen); //this is correct
rbuf->cp=malloc(rbuf->msglen);
memcpy(&rbuf->cp,rbuf+sizeof(int),sizeof(*rbuf));
printf("\nMESSAGE …Run Code Online (Sandbox Code Playgroud) 我从读取操作系统概念书中了解到,内存中的进程包括:文本部分,数据部分,堆栈和堆.
但我问的是,当创建此部分时,进程要求Kernel创建共享内存段?在堆?
另一个问题内核知道有关PCB格式的系统中每个进程的信息,并将此PCB保存在进程表中.
问题是:进程表双向链表是什么?
我运行代码时遇到问题.我的shmat失败并打印权限被拒绝.我搜索谷歌如何解决它,但我不能.我的代码如下:
#include <stdio.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#define ERROR -1
int main ( int argc, char *argv[] ) {
int shmid,key=50;
int *val;
int *x;
int rw = -1;
// 0 for write and 1 for read
shmid = shmget ( key, sizeof( int ), IPC_CREAT );
if ( shmid == -1 ) {
perror ( "Error in shmget\n" );
return ( ERROR );
}
val = ( int * …Run Code Online (Sandbox Code Playgroud) 我正在使用Qt C++我用于QSharedMemory限制应用程序的多个实例的位置来实现应用程序.相关代码段main.cpp如下,
QSharedMemory sharedMemory;
sharedMemory.setKey(SM_INSTANCE_KEY);
if (!sharedMemory.create(1))
{
QMessageBox::warning(0, "Console", "An instance of this application is already running!" );
exit(0); /* Exit, already a process is running */
}
Run Code Online (Sandbox Code Playgroud)
在打开应用程序时,我可以看到已为我的应用程序创建了共享内存.(shmid7045192,1B size)
到现在为止还挺好.当我的应用程序由于某种原因崩溃时出现问题.在崩溃时,sharedMemory没有被清除,因此我无法再打开该应用程序.当它崩溃时,附加的应用程序计数变为0,但共享内存不会被删除.相关的屏幕截图如下
根据我的理解,由于共享内存的状态没有dest像其他共享内存那样标记,即使没有任何附加进程也不会被删除.
所以,我的问题是,有没有办法将共享内存的状态标记为dest?
通常,共享内存是使用映射到进程地址空间的部分On-Disk文件实现的.每当在共享区域上发生内存访问时,文件系统就会在磁盘上写入更改,这是一个很大的开销.
通常,调用fopen()返回传递给mmap()的文件描述符以创建文件的内存映射.shm_open显然,工作方式相同.它返回它甚至可以与普通的文件操作(例如,使用的文件描述符ftruncate,ftell,fseek...等).我们指定一个字符串作为参数shm_open但不像fopen(),它不是可见文件系统上的真实文件的名称(已安装的HDD,闪存驱动器,SSD等).完全不相关的进程可以使用相同的字符串名称将相同的区域映射到其地址空间.
那么,传递给shm_open什么shm_open创建/打开的字符串参数是什么?它是一个临时文件系统(/ tmp)上的文件,最终被许多进程用来创建共享区域(嗯,我认为它必须是某种文件,因为它返回文件描述符)?或者它是由内核支持的某种神秘且隐藏的文件系统?
人们说shm_open比较快,fopen因为没有磁盘操作,所以我建议的理论是内核使用一个不可见的基于RAM的文件系统来实现共享内存shm_open!