我想使用共享内存将getaddrinfo结构(* res)的输出传递给父(来自子进程)进程,如下所示
pid = fork();
if (pid == 0)
{
.....
iStatus = getaddrinfo(argv[1], NULL, &hints, &servinfoC);
...
shmid = shmget(GETADDR_SHM_KEY, SHMSZ, IPC_CREAT | 0666);
....
shmC = shmat(shmid, (void*)NULL, 0));
memcpy(shmC, servinfoC, sizeof(struct addrinfo));
freeaddrinfo (servinfoC);
}
else
{
struct addrinfo *servinfoP;
while ((pid = waitpid (pid, &status, WUNTRACED | WCONTINUED)) > 0)
shmid = shmget(GETADDR_SHM_KEY, SHMSZ, 0666 | IPC_CREAT);
shmP = shmat(shmid, (void*)NULL, 0));
/*HELP Copy shmP to servinfoP struct*/
}
我尝试了memcpy但由于addrinfo需要内存分配而没有帮助。
提前感谢您的时间和帮助
此致 的Manoj
答案 0 :(得分:5)
这不起作用。 addrinfo结构包含指向其他内存区域的指针,最重要的是结果的链接列表。如果要通过共享内存传递它,则需要将其展平。
例如:
struct addrinfo_flat
{
int ai_family;
int ai_socktype;
int ai_protocol;
struct sockaddr_storage ai_addr;
socklen_t ai_addrlen;
};
struct addrinfo_flags *addrs = (struct addrinfo_flat*)shmC;
addrs->ai_family = ai->ai_family;
addrs->ai_socktype = ai->ai_socktype;
addrs->ai_protocol = ai->ai_protocol;
memcpy(&addrs->ai_addr, ai->ai_addr, ai->ai_addrlen);
addrs->ai_addrlen = ai->ai_addrlen;
(多项结果留作练习)
答案 1 :(得分:1)
尝试将父代码更改为:
struct addrinfo servinfoP;
while ((pid = waitpid (pid, &status, WUNTRACED | WCONTINUED)) > 0)
shmid = shmget(GETADDR_SHM_KEY, SHMSZ, 0666 | IPC_CREAT);
shmP = shmat(shmid, (void*)NULL, 0));
memcpy(&servinfoP, shmP, sizeof(struct addrinfo));
现在您不必担心servinfoP
的空间 - 当然如果您希望在当前环境之外提供此空间,那么您必须malloc
struct addrinfo* servinfoP = (struct addrinfo*) calloc(sizeof(struct addrinfo));
注意:这都不是c ++ ..
顺便说一句。如果你可以保证共享内存段在你需要addrinfo
的时间内可用,你可以简单地转换指针,例如
struct addrinfo* servinfoP = (struct addrinfo*) shmP;
同样,在这里你不需要单独分配......
答案 2 :(得分:1)
听起来我正在尝试使用fork
/进程实现异步DNS查找,这实际上是 坏主意。如果您不想要异步DNS库,只需使用线程而不是fork
。然后生成的struct addrinfo
已经在程序的地址空间中,并且可以被调用者使用(并释放)。
新线程应该调用getaddrinfo
并在调用者完成时通知他;用于通知调用者的方法应取决于程序的事件处理方式。假设它是单线程的,你可能正在使用select
/ poll
(或者像libevent
这样的抽象),所以线程可能有意义使用你可以使用的管道{ {1}} on表示查找完成的时间。
P.S。除了需要它的传统接口(如X11)之外,切勿使用select
等。有更清洁,更现代的方式来共享内存,例如shmget
和mmap
(对于您只能与MAP_SHARED|MAP_ANONYMOUS
ed孩子共享的匿名共享内存)或fork
(POSIX命名为共享内存)甚至普通文件的shm_open
......