免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1827 | 回复: 1
打印 上一主题 下一主题

[进程管理] 【共享内存shmat】关于使用shmat遇到的诡异问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2015-10-10 23:19 |只看该作者 |倒序浏览
目前在看书的时候看到进程间通信共享内存的一个例子本来就打算很简单的去linux上调试一下,结果发生非常让我难以理解的问题,我已经纠结一个晚上了。
主要问题是:
1、在shmget和shmat函数都没有问题,但是在使用shmat得到地址后无法对地址进行操作,我是在发现没有看到预期的打印后一步步加打印进行调试的,发现shmat后对addr无法操作。
2、还有一个问题是同一个父进程产生的几个子进程在使用shmat结果会一样吗?我试了几次结果都会一样的。但是看之前有帖子讨论貌似会不一样的。
具体的代码如下:
#include <stdio.h>
#include <sys/types.h>
#include <sys/msg.h>
#include <sys/ipc.h>
#include <stdlib.h>
#define SHMKEY                75
int shmid, i;
int *addr;

void CLIENT()
{
        printf("client\n");
        int i = 9;
        shmid = shmget(SHMKEY, 1024, 0777);
        if (-1 == shmid)
        {
                printf("create client key error\n");
        }
        addr = (int *)shmat(shmid, NULL, 0);
        if ((int *)-1 == addr)
        {
                printf("create client addr error\n");
        }
        else
        {
                printf("client addr %p\n", addr);
        }
        for(i = 9; i >= 0; i--)
        {
                printf("client_here1\n");
                while(*addr != -1);
                printf("client_here2\n");
                *addr = i;
                printf("client sent %d\n", *addr);
        }
        printf("out client\n");
        exit(0);
}

void SERVER()
{
        printf("server\n");
        shmid = shmget(SHMKEY, 1024, 0777|IPC_CREAT);
        if (-1 == shmid)
        {
                printf("create server key error\n");
        }
        addr = (int *)shmat(shmid, NULL, 0);
        if ((int *)-1 == addr)
        {
                printf("create server addr error\n");
        }
        else
        {
                printf("server addr %p\n", addr);
        }
        do
        {
                printf("server_here1\n");
                *addr = -1;
                printf("server_here2\n");
                while(*addr == -1);
                printf("server received %d\n", *addr);
        }while(*addr);
        shmctl(shmid, IPC_RMID, 0);//最后一个参数*buf
        printf("out server\n");
        exit(0);
}
void main()
{
        printf("in\n");
        while((i = fork()) == -1);
        if(!i)        SERVER();
        while((i = fork()) == -1);
        if(!i)        CLIENT();
        wait(NULL);
        wait(NULL);
        printf("out\n");
}


ubuntu 12.04调试结果是:
(我一共运行了很多次,截取其中三次)
in
server
server addr 0xfffffffff1d95000
server_here1
client
client addr 0xfffffffff1d95000
client_here1
out
/////////////////////////////////////////////
in
server
server addr 0x1f2c7000
server_here1
client
client addr 0x1f2c7000
client_here1
out
/////////////////////////////////
in
client
client addr 0xffffffff96122000
client_here1
server
server addr 0xffffffff96122000
server_here1
out

跪谢给位大大们的帮助!!!

论坛徽章:
0
2 [报告]
发表于 2016-04-28 23:06 |只看该作者
把你的程序运行了一下,改动三个地方即可:
1. fork的逻辑应该调整成:
                                 if (fork())
                                {
                                        SERVER();
                                }
                                else
                                {
                                        CLIENT();
                                }
    当前代码会嵌套生成过多的进程

2. 头文件需要加上 #include <sys/shm.h>

3. 将SHMID的生成放在main函数中且在fork之前,这样就可以同样被当前进程和子进程同时知道。强制的用75作为SHMKEY并不安全。
实例如下:
          shmid = shmget(IPC_PRIVATE, 1024, S_IRUSR|S_IWUSR);
          if (-1 == shmid)
          {
              printf("create key error\n");
          }

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP