问题

如题,我的win10上安装了wsl的ubuntu后(微软商店下载的wsl的Ubuntu)这个系统内部不支持POSIX的消息队列,虽然有<mqueue.h>头文件,但是没有实现,会报错。

如果想找个简单的办法呢,那就是用systemV的消息队列,可这是个虚拟机本地环境问题,我用virtualbox安装的虚拟机就能正常使用。所以肯定得解决这个问题,换成systemV的消息队列就有点「掩耳盗铃」的意味了。

测试

下面是一个POSIX消息队列的demo

#include <iostream>
#include <cstring>

#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <mqueue.h>

using namespace std;

int main()
{
    mqd_t mqID;
    mqID = mq_open("/testmQueue", O_RDWR | O_CREAT, 0666, NULL);

    if (mqID < 0)
    {
        cout<<"open message queue error..."<<strerror(errno)<<endl;
        return -1;
    }

    mq_attr mqAttr;
    if (mq_getattr(mqID, &mqAttr) < 0)
    {
        cout<<"get the message queue attribute error"<<endl;
        return -1;
    }

    cout<<"mq_flags:"<<mqAttr.mq_flags<<endl;
    cout<<"mq_maxmsg:"<<mqAttr.mq_maxmsg<<endl;
    cout<<"mq_msgsize:"<<mqAttr.mq_msgsize<<endl;
    cout<<"mq_curmsgs:"<<mqAttr.mq_curmsgs<<endl;
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.

如果编译后运行出现了下面的报错,代表当前系统不支持POSIX消息队列。当前系统下有mqueue头文件,但并没有函数的实现体

root@DESKTOP-5SQO6N0:~# ./test
open message queue error...No such file or directory
open message queue error...Function not implemented
  • 1.
  • 2.
  • 3.

解决

需要将wsl版本1改成版本2,否则无完整Linux内核支持,无法使用POSIX消息队列。这也是WSL版本1和2的重大区别之一。

用如下命令将当前虚拟机改成wsl2版本,就可以使用了。这部分命令上文也有介绍

wsl -l -v # 用这个命令查看当前version是不是1
wsl --update # 更新wsl
wsl --set-version 虚拟机名 2  # 把指定虚拟机改成版本2
  • 1.
  • 2.
  • 3.

再次测试

正常情况下,上面的消息队列代码应该输出如下内容

root@DESKTOP-5SQO6N0:~# ./test
mq_flags:0
mq_maxmsg:10
mq_msgsize:8192
mq_curmsgs:0
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

绑定目录

除了上面这个问题,在使用消息队列之前还可以monut一下路径,参考man手册中的教程(似乎不是必须要做的,mount了这个路径之后能更好地看到现有的消息队列)

mkdir /dev/mqueue
mount -t mqueue none /dev/mqueue
  • 1.
  • 2.