我正在尝试使用共享内存作为管道,我遇到了几个问题:
在return 0
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);
我不明白为什么不起作用。
在fork(2) the child inherits the attached shared memory segments.
所以我尝试在父亲和孩子身上使用shmdt
两次,但后来我收到错误
Invalid argument
打印“{main}”后main()
卡住时,我尝试使用ipcs -m
查看共享内存的状态,我看到nattch
为1,{{1}是0 ...
仅在key
ctrl+c
之后,内存段才会从main()
我不确定我应该带些什么进一步的信息。我没有写出所有的功能,因为这很多,我认为这不重要......
答案 0 :(得分:1)
我怀疑你对某事感到困惑。
最后一个输出是“end main”
shm_pipe_close()free指向段的指针并删除段
然而,正如所写的那样 - 在子块中没有exit
- 此代码应在父级和子级中运行 :
shm_pipe_close(spd[0]);
shm_pipe_close(spd[1]);
printf("end main\n");
换句话说,两次(除非孩子在shm_pipe_read
停滞,见下文)。如果“删除段”是指单个共享内存实体,那么这可能是无意的。
除此之外,您的结果取决于shm_pipe_read
和shm_pipe_write
是否像管道上的正常阻塞读/写调用一样工作,等待直到在另一端读取或写入数据。我猜你的写作当然不是而不是,而且可能也不是读。
这意味着shm_pipe_write
可能会在父级中发生,然后“管道”(实际上是共享的内存网段)会立即被删除。如果这导致shm_pipe_read
中的某些内容停止(因为该段已经消失),它可能(如评论中的ring0所述)解释您的问题。
答案 1 :(得分:0)
我认为你的问题就在这里:
shmid = shmget(key, PIPE_SIZE, IPC_CREAT | IPC_EXCL | 0600);
更改权限,以便子和父可以访问共享内存段:
shmid = shmget(key, PIPE_SIZE, IPC_CREAT | IPC_EXCL | 0666);
因为我不确切知道你的功能在做什么......这是一个类似的程序,你可以参考看看你是否有其他错误(顺便说一下 - 我把权限改为0600,我可以看到主要过程完成,但孩子挂起):
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
int main(int argc, char * argv[])
{
key_t key = 1111;
int shmid;
char *buff;
char *s;
char *addr = NULL;
if((shmid = shmget(key, 4096, IPC_CREAT | IPC_EXCL | 0666)) < 0 ) {
perror("shmget");
return -1;
}
if((buff = shmat(shmid, addr, 0)) == (char *)-1) {
perror("shmat");
return -1;
}
if(fork()){
printf("I'm the child\n");
while(strlen(buff) == 0) {}
for(s = buff; *s != NULL; s++)
putchar(*s);
printf("\nChild is done\n");
}
else {
printf("I'm the parent\n");
strcpy(buff, "hello world!\0");
printf("Parent is done.\n");
}
shmdt(addr);
shmctl(shmid, IPC_RMID, NULL);
return 0;
}