我正在尝试理解命令pipe(2)
,例如:
int pipefd[2];
if (pipe(pipefd) == -1) {
perror("pipe");
exit(EXIT_FAILURE);
}
我希望获得两个带有shared memory
的文件描述符,用于匿名管道(父子关系)。
例如,这是父子进程之间的简单对话:
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <sys/wait.h>
#include <unistd.h>
#include <string.h>
#define SHMSIZE 16
int main() {
int shmid;
char *shm;
if(fork() == 0) // child first
{
shmid = shmget(2009, SHMSIZE, 0);
shm = shmat(shmid, 0, 0);
char *s = (char *) shm;
*s = '\0';
int i;
// child enters the input that would be stored in the shared memory
for(i=0; i<3; i++) {
int n;
printf("Enter number<%i>: ", i);
scanf("%d", &n);
// convert the input into a c-string
sprintf(s, "%s%d", s, n);
}
strcat(s, "\n");
// display the contents of the shared memory
printf ("I'm the child process , and I wrote:%s\n",shm);
// detaches the shared memory segment
shmdt(shm);
}
else // parent
{
// get the segment
shmid = shmget(2009, SHMSIZE, 0666 | IPC_CREAT);
// attaching the segment to the father
shm = shmat(shmid, 0, 0);
// father waits for the son the finish
wait(NULL);
// father displays what the son wrote
printf ("I'm the father , and my child wrote :%s\n",shm) ;
// detaches the shared memory segment
shmdt(shm);
shmctl(shmid, IPC_RMID, NULL);
}
return 0;
}
输出非常简单:
Enter number<0>: 123
Enter number<1>: 567
Enter number<2>: 789
I'm the child process , and I wrote:123567789
I'm the father , and my child wrote :123567789
这是shm_pipe_pipe()
的实施,替代pipe(2)
:
int shm_pipe_pipe(int spd[2])
{
spd[0] = shmget(2009, SHMSIZE, 0);
spd[1] = shmget(2009, SHMSIZE, 0666 | IPC_CREAT);
if (spd[0] == -1 || spd[1] == -1)
return -1;
return 1;
}
我的问题是:
我知道fd[0]
用于阅读而fd[1]
用于写作,但是
他们究竟拥有什么?地址?
我上面写的函数shm_pipe_pipe
似乎不起作用,它有什么问题?
由于 `
答案 0 :(得分:8)
以下图片对磁盘文件有效。
如果有两个独立的过程:
如果是管道..
这是文件描述符表的一般视图
pipefd
返回的值填充文件描述符数组shmget()
。 来自man 2 shmget
shmget()返回共享内存段的标识符 与参数键的值相关联。一个新的共享内存 段,大小等于大小的值四舍五入到倍数 如果key的值为IPC_PRIVATE或key不是,则创建PAGE_SIZE IPC_PRIVATE,不存在与密钥对应的共享内存段,以及 IPC_CREAT在shmflg中指定。
了解shmget()的作用非常重要。它要求舍入大小(usnig系统的PAGE_SIZE
)。这段内存由密钥标识。因此内核维护一个密钥值表。该表还包含共享内存区域的地址。现在,当您调用shmat()
时,您使用shmid
查询此表,并且返回的地址附加了您的进程地址空间。
因此shmid
返回的shmget()
是系统维护的键值对表中的条目,与pipe()
使用的文件描述符无关。
底线是:
你无法以这种方式实施pipe
。你为什么不看看pipe
本身的实际实现?
虽然该文件中没有任何用处,因为它只调用其他__pipe
。您可以克隆git repo并使用cscope查找pipe
的实际实现。