This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center
                            
                        
                    
                
                                7年前关闭。
            
                    
我试图将共享内存用作管道,但遇到一些问题:


我无法删除该细分
return 0之后,main函数没有退出

int main()
{
  int spd[2], pid, rb;
  char buff[4096];
  if (shm_pipe_pipe(spd) < 0)
  {
        perror("shm_pipe_pipe");
        exit(1);
  }
  if (fork())
  {
        rb = shm_pipe_read(spd[0], buff, sizeof(buff));
        if (rb > 0)
                write(1, buff, rb);
  }
  else
  {
         shm_pipe_write(spd[1], "hello world!\n", sizeof("hello world!\n"));
  }

  shm_pipe_close(spd[0]);
  shm_pipe_close(spd[1]);
  printf("end main\n");
  return 0;
}



最后的输出是“ end main”,但是程序没有关闭并返回bash。
我肯定这与整个共享内存有关:

shm_pipe_pipe()分配共享内存段和指向共享内存的指针:

shmid = shmget(key, PIPE_SIZE, IPC_CREAT | IPC_EXCL | 0600);
buffer = (char*)shmat(pipes_array[i].m_shmid, NULL, 0)) == NULL)


shm_pipe_write and shm_pipe_read只需对共享内存执行memcpy()

shm_pipe_close() free指向该段的指针并删除该段:

shmdt(buffer);
shmctl(shmid, IPC_RMID, NULL);


我不明白为什么它不起作用。

它写在shmdt的手册页中,在fork(2) the child inherits the attached shared memory segments.之后

所以我尝试在父亲和孩子上两次使用shmdt,但随后出现错误

Invalid argument


当打印“ end main”后main()卡住时,我尝试查看与ipcs -m共享的内存的状态,我看到nattch为1,而key为0 ...
仅在ctrl+c main()之后,内存段才从ipcs -m删除

我不确定应该携带什么进一步的信息。我没有编写所有的函数,原因很多,我也不认为这很重要...

最佳答案

我怀疑您对某些事情感到困惑。


  最后的输出是“ end main”
  
  shm_pipe_close()释放指向该段的指针并删除该段


但是按照编写的方式-子块中没有exit,该代码应同时在父级和子级中运行:

  shm_pipe_close(spd[0]);
  shm_pipe_close(spd[1]);
  printf("end main\n");


换句话说,两次(除非孩子停在shm_pipe_read中,请参阅下文)。如果“删除段”是指单个共享的mem实体,则可能是无意的。

除此之外,您的结果还取决于shm_pipe_readshm_pipe_write是否像正常阻塞管道上的读取/写入调用那样工作,直到管道另一端读取或写入数据为止。我猜您的写法肯定不是那样,读的也可能不是。

这意味着shm_pipe_write可能在父对象中发生,然后立即删除“管道”(实际上是共享的内存段)。如果这导致shm_pipe_read中的某些内容停顿(因为该段已消失),则可能(如ring0在评论中所述)解释了您的问题。

关于c - 返回0后主函数不会退出,shmctl不会删除段,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/14282443/

10-12 07:36
查看更多