【发布时间】:2021-06-14 02:36:10
【问题描述】:
我正在使用 mmap 使用共享内存实现 IPC。我用于共享的结构是
struct shared{
sem_t P;
sem_t C;
sem_t M;
int prod_status;
char** queue;
int buffer_size;
int queue_start;
int queue_after_last; //pointing to buffer index after the last element in the buffer
int queue_count;
};
缓冲区的大小作为命令行参数传递。
int main(int agrc, char* argv[]){
int N_buff=atoi(argv[1]);
struct shared* shared_data=(struct shared*)mmap(NULL,sizeof(struct shared),PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANONYMOUS,-1,0);
//printf("hello\n");
shared_data->buffer_size=N_buff;
shared_data->queue=(char**)mmap(NULL,sizeof(N_buff),PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANONYMOUS,-1,0);
for(int i=0;i<N_buff;i++){
shared_data->queue[i]=(char*)mmap(NULL,70*sizeof(char),PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANONYMOUS,-1,0);
}
shared_data->queue_start=0;
shared_data->queue_after_last=0;
shared_data->queue_count=0;
shared_data->prod_status=1;
sem_init(&shared_data->P,1,N_buff);
sem_init(&shared_data->C,1,0);
sem_init(&shared_data->M,1,1);};
队列被其他进程访问。我将队列用作管道。 问题是,每次我使用分配内存时
shared_data->queue[i]=(char*)mmap(NULL,70*sizeof(char),PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANONYMOUS,-1,0);
它将分配整个内存页面。是否有任何其他使用 mmap 实现此内存有效的方法? 我在这段代码之后使用 fork 来生成一个子进程,所以我想我可以使用这种方法在父子之间使用 IPC 指针。
【问题讨论】:
-
我根本不明白这种方法是如何工作的。您将指针存储在进程共享缓冲区中,但一个进程的指针对其他进程没有意义。即使它们指向映射的内存也不行。
-
它将分配整个内存页面。共享映射必须页面对齐并且是页面大小的倍数。这里真的没有效率低下。您可能有竞争条件。您没有显示 other 客户端代码,因此它可能会在
sem_init调用生效之前访问该区域。 -
正如约翰所说,您不能在共享内存中使用指针。 除非您正在执行
fork然后调用子函数(即它将继承父内存映射)。如果您有 两个 客户端进行类似的设置,正如 John 所提到的,它不会工作。最好计算所有共享数据的总大小并将其映射为一个巨大的区域。您可以将指针替换为从共享区域开始的 [byte] 偏移量。 -
对不起,我忘了提到我在提到的代码之后使用了 fork。沟通发生在父母和孩子之间。
-
好的,然后
sem_init上的 no 竞争条件。那么,问题是什么?代码not以什么方式工作?
标签: c ipc shared-memory mmap