搜索
首页系统教程LINUXLinux IPC POSIX 消息队列:一种实现可靠消息传递的简单方式

Linux IPC POSIX 消息队列:一种实现可靠消息传递的简单方式

Feb 10, 2024 pm 02:45 PM
linuxlinux教程linux系统linux命令外壳脚本嵌入式linuxlinux入门linux学习

Linux系统是一种支持多任务并发执行的操作系统,它可以同时运行多个进程,从而提高系统的利用率和效率。但是,如果这些进程之间需要进行数据交换和协作,就需要使用一些进程间通信(IPC)的方式,例如信号、共享内存、信号量等。其中,POSIX 消息队列是一种比较简单而可靠的IPC方式,它可以让两个或多个进程通过一个队列来进行消息传递,无需关心消息的内容和格式。本文将介绍Linux系统中POSIX 消息队列的方法,包括消息队列的创建、打开、发送、接收、关闭和删除等方面。

Linux IPC POSIX 消息队列:一种实现可靠消息传递的简单方式

模型:

#include
#include 
#include 
mq_open()   //创建/获取消息队列fd       
mq_get()    //设置/获取消息队列属性   
mq_send()/mq_receive()    //发送/接收消息 
mq_close()      //脱接消息队列            
mq_unlink()     //删除消息队列            

POSIX mq VS Sys V mq的优势

  • 更简单的基于文件的应用接口
  • 完全支持消息优先级(优先级最终决动队列中消息的位置)
  • 完全支持消息到达的异步通知,这通过信号或是线程创建实现
  • 用于阻塞发送与接收操作的超时机制

消息队列名

$man mq_overview知:消息队列由一个形如’/somename’的名字唯一标识,名字字符串的最大长度不能朝着哦NAME_MAX(i.e.,255),两个进程通过使用同一个消息队列的名字来通信

mq_open()

//创建一个POSIX消息队列或打开一个已经存在的消息队列,成功返回消息队列描述符mqdes供其他函数使用,失败返回

(mqd_t)-1设errno
//Link with -lrt.
mqd_t mq_open(const char *name, int oflag);
mqd_t mq_open(const char *name, int oflag, mode_t mode, struct mq_attr *attr);

oflag
must include one of:

  • O_RDONLY表示以只接收消息的形式打开消息队列
  • O_WRONLY表示以只发送消息的形式打开消息队列
  • O_RDWR表示以可接收可发送的形式打开消息队列

can be Bitwised ORed:

  • O_NONBLOCK以nonblocking的模式打开消息队列
  • O_CREAT如果一个消息队列不存在就创建它,消息队列的拥有者的UID被设为调用进程的effective UID,GID被设为调用进程的effective GID
  • O_EXCL确保消息队列被创建,如果消息队列已经存在,则发生错误

mode如果oflag里有O_CREAT,则mode用来表示新创建的消息队列的权限
attr如果oflag里有O_CREAT,则attr表示消息队列的属性,如果attr是NULL,则会按照默认设置配置消息队列(mq_overview(7) for details.)

mq_setattr() / mq_getattr()

//设置/修改 / 获取消息队列属性,成功返回0,失败返回-1设errno
//Link with -lrt.
int mq_setattr(mqd_t mqdes, const struct mq_attr *newattr, struct mq_attr *oldattr);
int mq_getattr(mqd_t mqdes, struct mq_attr *attr);

mqattr结构体

struct mq_attr {
    long mq_flags;      /* Flags: 0 or O_NONBLOCK */
    long mq_maxmsg;     /* Max. # of messages on queue */
    long mq_msgsize;    /* Max. message size (bytes) */
    long mq_curmsgs;    /* # of messages currently in queue */
};

mq_send() / mq_timesend()

//发送消息到mqdes指向的消息队列。成功返回0,失败返回-1设errno
//Link with -lrt.
int mq_send(mqd_t mqdes, const char *msg_ptr,size_t msg_len, unsigned int msg_prio);

//如果消息队列满
#include        //额外的header
int mq_timedsend(mqd_t mqdes, const char *msg_ptr,size_t msg_len, unsigned int msg_prio,
const struct timespec *abs_timeout);

msg_len msg_ptr指向的消息队列的长度,这个长度必须msg_prio 一个用于表示消息优先级的非0整数,消息按照优先级递减的顺序被放置在消息队列中,同样优先级的消息,新的消息在老的之后,如果消息队列满了,就进入blocked状态,新的消息必须等到消息队列有空间了进入,或者调用被signal中断了。如果flag里有O_NOBLOCK选项,则此时会直接报错
abs_timeout:如果消息队列满了,那么就根据abs_timeout指向的结构体表明的时间进行锁定,里面的时间是从970-01-01 00:00:00 +0000 (UTC)开始按微秒计量的时间,如果时间到了,那么mq_timesend()立即返回

struct timespec {
    time_t tv_sec;        /* seconds */
    long   tv_nsec;       /* nanoseconds */
};

mq_receive()/mq_timedreceive()

//从消息队列中取出优先级最高的里面的最老的消息,成功返回消息取出消息的大小,失败返回-1设errno
//具体功能参照mq_send()/mq_timesend()
//Link with -lrt.
ssize_t mq_receive(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned int *msg_prio);
#include        //额外的header
ssize_t mq_timedreceive(mqd_t mqdes, char *msg_ptr, size_t msg_len,
 unsigned int *msg_prio, const struct timespec *abs_timeout);

mq_notify()

//允许调用进程注册或去注册同步来消息的通知,成功返回0,失败返回-1设errno
//Link with -lrt.
int mq_notify(mqd_t mqdes, const struct sigevent *sevp);

sevp指向sigevent的指针

  • 如果sevp不是NULL,那么这个函数就将调用进程注册到通知进程,只有一个进程可以被注册为通知进程
  • 如果sevp是NULL且当前进程已经被注册过了,则去注册,以便其他进程注册
union sigval {                  /* Data passed with notification */
    int     sival_int;          /* Integer value */
    void*   sival_ptr;          /* Pointer value */
};
struct sigevent {
    int     sigev_notify;       /* Notification method */
    int     sigev_signo;        /* Notification signal */
    union sigval    sigev_value;    /* Data passed with notification */
    void(*sigev_notify_function) (union sigval); //Function used for thread notification
 (SIGEV_THREAD)
    void*   sigev_notify_attributes;    // Attributes for notification thread (SIGEV_THREAD)
    pid_t   sigev_notify_thread_id;     /* ID of thread to signal (SIGEV_THREAD_ID) */
};

sigev_notify使用下列的宏进行配置:

  • SIGEV_NONE调用进程仍旧被注册,但是有消息来的时候什么都不通知
  • SIGEV_SIGNAL通过给调用进程发送sigev_signo指定的信号来通知进程有消息来了
  • SIGEV_THREAD一旦有消息到了,就激活sigev_notify_function作为新的线程的启动函数

mq_close()

//关闭消息队列描述符mqdes,如果有进程存在针对这个队列的notification request,那么也会被移除

//成功返回0,失败返回-1设errno
//Link with -lrt.
int mq_close(mqd_t mqdes);
//移除队列名指定的消息队列,一旦最后一个进程关闭了针对这个消息队列的描述符,就会销毁这个消息队列
//成功返回0,失败返回-1设errno
//Link with -lrt.
int mq_unlink(const char *name);

本文介绍了Linux系统中POSIX 消息队列的方法,包括消息队列的创建、打开、发送、接收、关闭和删除等方面。通过了解和掌握这些知识,我们可以更好地使用POSIX 消息队列来实现进程间通信,提高系统的稳定性和效率。当然,Linux系统中POSIX 消息队列还有很多其他的特性和用法,需要我们不断地学习和研究。希望本文能给你带来一些启发和帮助。

以上是Linux IPC POSIX 消息队列:一种实现可靠消息传递的简单方式的详细内容。更多信息请关注PHP中文网其他相关文章!

声明
本文转载于:良许Linux教程网。如有侵权,请联系admin@php.cn删除
Linux和Windows处理设备驱动程序的区别有什么区别?Linux和Windows处理设备驱动程序的区别有什么区别?Apr 25, 2025 am 12:13 AM

Linux和Windows在处理设备驱动程序上的差异主要体现在驱动管理的灵活性和开发环境上。1.Linux采用模块化设计,驱动可以动态加载和卸载,开发者需深入理解内核机制。2.Windows依赖微软生态,驱动需通过WDK开发并签名认证,开发相对复杂但保证了系统的稳定性和安全性。

比较和对比Linux和Windows的安全模型。比较和对比Linux和Windows的安全模型。Apr 24, 2025 am 12:03 AM

Linux和Windows的安全模型各有优势。Linux提供灵活性和可定制性,通过用户权限、文件系统权限和SELinux/AppArmor实现安全。Windows则注重用户友好性,依赖WindowsDefender、UAC、防火墙和BitLocker保障安全。

Linux和Windows之间的硬件兼容性有何不同?Linux和Windows之间的硬件兼容性有何不同?Apr 23, 2025 am 12:15 AM

Linux和Windows在硬件兼容性上不同:Windows有广泛的驱动程序支持,Linux依赖社区和厂商。解决Linux兼容性问题可通过手动编译驱动,如克隆RTL8188EU驱动仓库、编译和安装;Windows用户需管理驱动程序以优化性能。

Linux和Windows之间虚拟化支持有哪些差异?Linux和Windows之间虚拟化支持有哪些差异?Apr 22, 2025 pm 06:09 PM

Linux和Windows在虚拟化支持上的主要区别在于:1)Linux提供KVM和Xen,性能和灵活性突出,适合高定制环境;2)Windows通过Hyper-V支持虚拟化,界面友好,与Microsoft生态系统紧密集成,适合依赖Microsoft软件的企业。

Linux系统管理员的主要任务是什么?Linux系统管理员的主要任务是什么?Apr 19, 2025 am 12:23 AM

Linux系统管理员的主要任务包括系统监控与性能调优、用户管理、软件包管理、安全管理与备份、故障排查与解决、性能优化与最佳实践。1.使用top、htop等工具监控系统性能,并进行调优。2.通过useradd等命令管理用户账户和权限。3.利用apt、yum管理软件包,确保系统更新和安全。4.配置防火墙、监控日志、进行数据备份以确保系统安全。5.通过日志分析和工具使用进行故障排查和解决。6.优化内核参数和应用配置,遵循最佳实践提升系统性能和稳定性。

很难学习Linux吗?很难学习Linux吗?Apr 18, 2025 am 12:23 AM

学习Linux并不难。1.Linux是一个开源操作系统,基于Unix,广泛应用于服务器、嵌入式系统和个人电脑。2.理解文件系统和权限管理是关键,文件系统是层次化的,权限包括读、写和执行。3.包管理系统如apt和dnf使得软件管理方便。4.进程管理通过ps和top命令实现。5.从基本命令如mkdir、cd、touch和nano开始学习,再尝试高级用法如shell脚本和文本处理。6.常见错误如权限问题可以通过sudo和chmod解决。7.性能优化建议包括使用htop监控资源、清理不必要文件和使用sy

Linux管理员的薪水是多少?Linux管理员的薪水是多少?Apr 17, 2025 am 12:24 AM

Linux管理员的平均年薪在美国为75,000至95,000美元,欧洲为40,000至60,000欧元。提升薪资可以通过:1.持续学习新技术,如云计算和容器技术;2.积累项目经验并建立Portfolio;3.建立职业网络,拓展人脉。

Linux的主要目的是什么?Linux的主要目的是什么?Apr 16, 2025 am 12:19 AM

Linux的主要用途包括:1.服务器操作系统,2.嵌入式系统,3.桌面操作系统,4.开发和测试环境。Linux在这些领域表现出色,提供了稳定性、安全性和高效的开发工具。

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

SublimeText3 英文版

SublimeText3 英文版

推荐:为Win版本,支持代码提示!

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

功能强大的PHP集成开发环境

MinGW - 适用于 Windows 的极简 GNU

MinGW - 适用于 Windows 的极简 GNU

这个项目正在迁移到osdn.net/projects/mingw的过程中,你可以继续在那里关注我们。MinGW:GNU编译器集合(GCC)的本地Windows移植版本,可自由分发的导入库和用于构建本地Windows应用程序的头文件;包括对MSVC运行时的扩展,以支持C99功能。MinGW的所有软件都可以在64位Windows平台上运行。

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

将Eclipse与SAP NetWeaver应用服务器集成。

Atom编辑器mac版下载

Atom编辑器mac版下载

最流行的的开源编辑器