打印
[C语言]

进程间通讯-消息队列错误:msgrcv: Identifier removed

[复制链接]
2563|8
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
最近在学习linux 进程间通讯,自己写了段代码做测试,第一次实验比较成功,但是第二次运行的时候就出现错误:msgrcv: Identifier removed, 看信息应该是msgctl的IPC_RMID操作的问题,现在我有三个问题拜托大神一一解答:代码如下:
(1):为什么第一次成功而后面几次的运行就会报错?
(2):如果说是删除了消息队列的原因,可是第二次,第三次运行的时候代码又创建了消息队列啊为什么还是不行?
(3):如果不能在程序中删除消息队列,那消息队列不用了怎么删除呢?


#define BUF_SIZE 512

struct msgsag {
        long msg_type;
        char msg_text[BUF_SIZE];
};

int main(int argc, const char *argv[])
{
        key_t key;
        int msgid;
        struct msgsag msg;

        //获取key值
        if((key = ftok(".", 1)) == -1)
        {
                perror("ftok\n");

                exit(1);
        }

//创建消息队列  (第二次运行的时候又创建了啊)
        if(msgid = msgget(key, IPC_CREAT|0666) == -1)
        {
                perror("msgget");

                exit(1);
        }

        do
        {
                memset(msg.msg_text, 0, BUF_SIZE);

                if(msgrcv(msgid, (void *)&msg, sizeof(msg.msg_text), (long) 0, 0) == -1)
                {
                        perror("msgrcv");

                        exit(1);
                }

                printf("msg_type = %ld, msg_text = %s\n", msg.msg_type, msg.msg_text);

      }while(strncmp(msg.msg_text, "quit", 4));

        //从系统内核中移除消息队列
        if(msgctl(msgid, IPC_RMID, NULL) == -1)
        {
                perror("msgctl");

                exit(1);
        }

        return 0;
}


相关帖子

沙发
john_lee| | 2018-8-15 16:57 | 只看该作者
谁调用 msgsnd?

使用特权

评论回复
板凳
yanghelovehuang|  楼主 | 2018-8-16 10:42 | 只看该作者

msgsnd是我写的另一个进程 和他进行通讯的 代码:#define BUF_SIZE 512

struct msgsag {
        long msg_type;
        char msg_text[BUF_SIZE];
};

int main(int argc, const char *argv[])
{
        int msgid;
        key_t key;
        struct msgsag msg;

        //根据不同的路径和关键词产生不同的key
        if(key = ftok(".", 1) == -1)
                perror("ftok\n");

        //创建消息队列
        if(msgid = msgget(key, 0666|IPC_CREAT) == -1)
                perror("msgget\n");

        while(1)
        {
        msg.msg_type = getpid();
        if((fgets(msg.msg_text, BUF_SIZE, stdin)) == NULL)
        {
                perror("fgets\n");
                exit(1);
        }

        //发送消息
        if(msgsnd(msgid, &msg, strlen(msg.msg_text), 0) == -1)
        {
                perror("msgsnd\n");
                exit(1);
        }

        if(strncmp(msg.msg_text, "quit", 4) == 0)
                break;
        }

        return 0;
}

使用特权

评论回复
地板
john_lee| | 2018-8-16 13:06 | 只看该作者
本帖最后由 john_lee 于 2018-8-16 13:18 编辑

把接收程序的
if(msgid = msgget(key, 0666|IPC_CREAT) == -1)
改为
if ((msgid = msgget(key, 0666|IPC_CREAT)) == -1)


把发送程序的
if(msgid = msgget(key, 0666|IPC_CREAT) == -1)
改为
if ((msgid = msgget(key, 0666)) == -1)

使用特权

评论回复
5
yanghelovehuang|  楼主 | 2018-8-16 16:08 | 只看该作者
本帖最后由 yanghelovehuang 于 2018-8-16 16:10 编辑
john_lee 发表于 2018-8-16 13:06
把接收程序的
改为

谢谢您的回答 按照您的方法改了 是不出现那个错误了,可是运行两个进程之后添加消息后 接收消息的进程接收不到消息了 如图:想实现的是上面的现象一添加信息,接收端就会就收并打印,可是现在添加信息了接收端好像接收不到信息 没有打印信息 没反应


Ubuntu-2018-08-16-16-07-48.png (442.55 KB )

Ubuntu-2018-08-16-16-07-48.png

使用特权

评论回复
6
yanghelovehuang|  楼主 | 2018-8-16 16:23 | 只看该作者
john_lee 发表于 2018-8-16 13:06
把接收程序的
改为

我实验了一下是msgid 队列标识符不一样了, 没改之前都是0 改了之后 不一样了,这个是不是因为两个进程创建两次创建了两个不同的消息队列?

使用特权

评论回复
7
yanghelovehuang|  楼主 | 2018-8-16 16:45 | 只看该作者
john_lee 发表于 2018-8-16 13:06
把接收程序的
改为

解决了 大神 谢谢您啊 是我if(ftok)的时候也忘了加括号,问下大神这个括号什么作用啊 影响挺大的 之前我觉得加不加都一样

使用特权

评论回复
8
john_lee| | 2018-8-16 17:46 | 只看该作者
“赋值的优先级”比“比较操作符的优先级”低。
A = B == C,将先比较 B 与 C,B == C 实际上是一个表达式,相等则表达式为 1,不等为 0,然后将这个值赋值给 A。
(A = B) == C,先把 B 赋值给 A,然后与 C 比较。

使用特权

评论回复
9
yanghelovehuang|  楼主 | 2018-8-17 09:22 | 只看该作者
john_lee 发表于 2018-8-16 17:46
“赋值的优先级”比“比较操作符的优先级”低。
A = B == C,将先比较 B 与 C,B == C 实际上是一个表达式 ...

明白了  以前还真不知道他俩啥区别 ,谢谢您能回复,真的谢谢您

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

156

主题

324

帖子

1

粉丝