linux共享内存通信问题

hanyunqi 2012-07-27 10:13:21
我想通过共享内存(shmget/shmat/shmdt/shmctl)实现父子进程间的通信(fork())。
主要内容就是,申请一段共享内存,子进程向这段内存中写数据,父进程读出来。
可是,我在子进程中写完了,在子进程中可以读,在父进程中却读不出来。
这个问题,已经困扰我一天了,求大神帮忙。
源代码如下:

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <malloc.h>
#include <sys/stat.h>
#include <string.h>

int main(int argc, char* argv[])
{
int shm_id, shm_key = 12345;
unsigned short errno;
void **shmptr;
shm_id = shmget((key_t)shm_key, (size_t)(sizeof(char) * 100), IPC_CREAT|0666);
if (shm_id < 0)
{
printf("change the shm_key\n.");
return 0;
}
printf("shm_id = %d\n", shm_id);

shmptr = new void *;
*shmptr = NULL;


pid_t pid;
int count=0;
pid = fork();
printf( "This is first time, pid = %d\n", pid );
printf( "This is secONd time, pid = %d\n", pid );
if ( pid>0 )
{

*shmptr = (char *)shmat(shm_id, 0, 0);
if (*shmptr == (void *)-1)
{
printf("shmat fail.\n");
perror("shmat error");
return 0;
}
//sleep(1);
printf( "This is the parent Process.\n");
printf("%s\n",shmptr);

}
else if ( 0 == pid )
{
*shmptr = (char *)shmat(shm_id, 0, 0);
if (*shmptr == (void *)-1)
{
printf("shmat fail.\n");
perror("shmat error");
return 0;
}
printf( "This is the child Process.\n");
strcpy((char *)shmptr, "123qweasd123");
printf("%s\n",shmptr);
}
else
{
printf( "fork failed.\n" );
}
printf( "This is third time, pid = %d\n", pid );
printf( "This is fouth time, pid = %d\n", pid );
//printf("%s\n",shmptr);




//释放共享内存
if (-1 == shmdt(shmptr))
{
printf("shmdt == -1\n");
perror("shmdt error");
return 0;
}
if (-1 == shmctl(shm_id, IPC_RMID, 0))
{
printf("shmctl == -1\n");
return 0;
}
return 0;
}


运行结果如下:
shm_id = 2261058
This is first time, pid = 0
This is secONd time, pid = 0
This is the child Process.
123qweasd123
This is third time, pid = 0
This is fouth time, pid = 0
shmdt == -1
shmdt error: Invalid argument
This is first time, pid = 13324
This is secONd time, pid = 13324
This is the parent Process.

This is third time, pid = 13324
This is fouth time, pid = 13324
shmdt == -1
shmdt error: Invalid argument
...全文
269 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
诚朴勇毅 2012-07-27
  • 打赏
  • 举报
回复
换成C++代码吧

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <malloc.h>
#include <sys/stat.h>
#include <string.h>

int main(int argc, char* argv[])
{
int shm_id, shm_key = 12345;
unsigned short errno;
void **shmptr;
shm_id = shmget((key_t)shm_key, (size_t)(sizeof(char) * 100), IPC_CREAT|0666);
if (shm_id < 0)
{
printf("change the shm_key\n.");
return 0;
}
printf("shm_id = %d\n", shm_id);

shmptr = new void *;
*shmptr = NULL;


pid_t pid;
int count=0;
pid = fork();
printf( "This is first time, pid = %d\n", pid );
printf( "This is secONd time, pid = %d\n", pid );
if ( pid>0 )
{

*shmptr = (char *)shmat(shm_id, 0, 0);
if (*shmptr == (void *)-1)
{
printf("shmat fail.\n");
perror("shmat error");
return 0;
}
//sleep(1);
printf( "This is the parent Process.\n");
printf("%s\n",shmptr);

}
else if ( 0 == pid )
{
*shmptr = (char *)shmat(shm_id, 0, 0);
if (*shmptr == (void *)-1)
{
printf("shmat fail.\n");
perror("shmat error");
return 0;
}
printf( "This is the child Process.\n");
strcpy((char *)shmptr, "123qweasd123");
printf("%s\n",shmptr);
}
else
{
printf( "fork failed.\n" );
}
printf( "This is third time, pid = %d\n", pid );
printf( "This is fouth time, pid = %d\n", pid );
//printf("%s\n",shmptr);




//释放共享内存
if (-1 == shmdt(shmptr))
{
printf("shmdt == -1\n");
perror("shmdt error");
return 0;
}
if (-1 == shmctl(shm_id, IPC_RMID, 0))
{
printf("shmctl == -1\n");
return 0;
}
return 0;
}
追风筝的猪 2012-07-27
  • 打赏
  • 举报
回复
这个shmat函数
成功时,这个函数返回共享内存的起始地址
失败时返回-1

所以你的printf("%s\n",shmptr);
地址就是错的 该是*shmptr
追风筝的猪 2012-07-27
  • 打赏
  • 举报
回复
shm_id = 393226
This is first time, pid = 0
This is secONd time, pid = 0
This is the child Process.
123qweasd123
This is first time, pid = 24690
This is secONd time, pid = 24690
This is the parent Process.
123qweasd123
追风筝的猪 2012-07-27
  • 打赏
  • 举报
回复
[root@localhost test]# ./fork
shm_id = 393226
This is first time, pid = 0
This is secONd time, pid = 0
This is the child Process.
123qweasd123
This is third time, pid = 0
This is fouth time, pid = 0
shmdt == -1
shmdt error: Invalid argument
This is first time, pid = 24116
This is secONd time, pid = 24116
This is the parent Process.

This is third time, pid = 24116
This is fouth time, pid = 24116
shmdt == -1
shmdt error: Invalid argument
[root@localhost test]#

追风筝的猪 2012-07-27
  • 打赏
  • 举报
回复
试试 判断确定为父进程的时候 先加上个sleep(1);因为fork()父子进程的执行顺序是不确定的。
allenbein 2012-07-27
  • 打赏
  • 举报
回复
错了错了,进程的话应该用wait或者waitpid这两个函数来等子进程退出,pthread_join是用于线程通信的。
allenbein 2012-07-27
  • 打赏
  • 举报
回复
有可能子进程运行了一半,父进程已经退了,子进程也被迫退了。fork一个子进程是需要时间的。在父进程中加一个pthread_join函数来等子进程结束,然后父进程再往下运行。
你试一下

64,637

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧