• 首页
  • 搜索
  • 工具
  • 分类
  • 日志
  • 友链
  • 图片

It's Geek KingYoungy

KEEP CHALLENGE

标签 POSIX IPC 下的文章

多进程/多线程并发编程

POSIX进程间通信技术详解

2025-03-23 浏览量 142 暂无评论

POSIX IPC机制详解:消息队列、信号量与共享内存

在操作系统的多进程协作中,POSIX IPC(可移植操作系统接口进程间通信)提供了一套标准化的进程间通信机制,涵盖消息队列、信号量和共享内存三种核心方式。相较于传统的System V IPC,POSIX IPC具有更简洁的API设计和更高的跨平台兼容性。本文将深入解析这三种机制的系统调用及其实现细节。


一、消息队列(Message Queues)

消息队列是一种基于链表的异步通信机制,支持消息的优先级和非阻塞读写。

1. mq_open:创建或打开消息队列

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

mqd_t mq_open(const char *name, int oflag, mode_t mode, struct mq_attr *attr);

• 功能:创建或打开一个消息队列。
• 参数:
• name:队列名称,以/开头且不含其他/(如/my_queue)。
• oflag:标志位,常用组合:

◦ `O_RDONLY`:只读模式
◦ `O_WRONLY`:只写模式
◦ `O_RDWR`:读写模式
◦ `O_CREAT`:若不存在则创建
◦ `O_EXCL`:与`O_CREAT`联用,确保创建新队列
◦ `O_NONBLOCK`:非阻塞模式

• mode:权限位(如0666),控制队列的读/写权限。
• attr:指向mq_attr结构体的指针,定义队列属性:

struct mq_attr {
    long mq_flags;    // 标志(通常为0)
    long mq_maxmsg;   // 队列最大消息数
    long mq_msgsize;  // 单条消息最大长度
    long mq_curmsgs;  // 当前队列中的消息数(仅读)
};

• 返回值:成功返回消息队列描述符(mqd_t),失败返回-1。


2. mq_send / mq_receive:发送与接收消息

int mq_send(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned msg_prio);
int mq_receive(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned *msg_prio);

• 功能:向队列发送或从队列接收消息。
• 参数:
• mqdes:消息队列描述符。
• msg_ptr:消息缓冲区指针。
• msg_len:消息长度(需≤mq_msgsize)。
• msg_prio:消息优先级(0最低,MQ_PRIO_MAX由系统定义)。
• 返回值:成功返回0(mq_send)或接收的字节数(mq_receive),失败返回-1。


3. mq_close / mq_unlink:关闭与删除队列

int mq_close(mqd_t mqdes);
int mq_unlink(const char *name);

• 功能:关闭队列描述符或删除队列实体。
• 参数:
• mqdes:待关闭的描述符。
• name:待删除的队列名称。
• 返回值:成功返回0,失败返回-1。


二、信号量(Semaphores)

信号量用于进程间的同步控制,支持二进制和计数两种类型。

1. sem_open:创建或打开命名信号量

#include <semaphore.h>

sem_t *sem_open(const char *name, int oflag, mode_t mode, unsigned int value);

• 功能:创建或打开一个命名信号量。
• 参数:
• name:信号量名称(格式同消息队列)。
• oflag:标志位(O_CREAT、O_EXCL等)。
• mode:权限位(如0666)。
• value:信号量初始值。
• 返回值:成功返回信号量指针,失败返回SEM_FAILED。


2. sem_init / sem_destroy:初始化与销毁匿名信号量

int sem_init(sem_t *sem, int pshared, unsigned int value);
int sem_destroy(sem_t *sem);

• 功能:初始化或销毁匿名信号量(仅限线程或进程内使用)。
• 参数:
• sem:信号量指针。
• pshared:共享标志(0表示线程间,非0表示进程间)。
• value:初始值。
• 返回值:成功返回0,失败返回-1。


3. sem_wait / sem_post:P/V操作

int sem_wait(sem_t *sem);     // P操作(阻塞直到信号量>0)
int sem_trywait(sem_t *sem);  // 非阻塞P操作
int sem_post(sem_t *sem);     // V操作(信号量+1)

• 功能:执行信号量的增减操作。
• 参数:sem:信号量指针。
• 返回值:成功返回0,失败返回-1。


三、共享内存(Shared Memory)

共享内存允许进程直接访问同一块物理内存,是IPC中最高效的方式。

1. shm_open:创建或打开共享内存对象

#include <sys/mman.h>
#include <sys/stat.h>

int shm_open(const char *name, int oflag, mode_t mode);

• 功能:创建或打开共享内存对象。
• 参数:
• name:对象名称(格式同消息队列)。
• oflag:标志位(O_CREAT、O_RDWR等)。
• mode:权限位(如0666)。
• 返回值:成功返回文件描述符,失败返回-1。


2. ftruncate:调整共享内存大小

int ftruncate(int fd, off_t length);

• 功能:设置共享内存对象的长度。
• 参数:
• fd:共享内存文件描述符。
• length:目标长度(字节)。
• 返回值:成功返回0,失败返回-1。


3. mmap / munmap:映射与解除映射

void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
int munmap(void *addr, size_t length);

• 功能:将共享内存映射到进程地址空间或解除映射。
• 参数:
• addr:映射起始地址(通常设为NULL由系统选择)。
• length:映射长度。
• prot:保护模式:

◦ `PROT_READ`:可读
◦ `PROT_WRITE`:可写
◦ `PROT_EXEC`:可执行
◦ `PROT_NONE`:不可访问

• flags:映射标志:

◦ `MAP_SHARED`:多进程共享
◦ `MAP_PRIVATE`:私有映射(写时复制)

• fd:共享内存文件描述符。
• offset:文件偏移量(通常为0)。
• 返回值:成功返回映射地址指针(mmap)或0(munmap),失败返回MAP_FAILED或-1。


4. shm_unlink:删除共享内存对象

int shm_unlink(const char *name);

• 功能:删除共享内存对象。
• 参数:name:对象名称。
• 返回值:成功返回0,失败返回-1。


总结

POSIX IPC通过标准化的API设计,为进程间通信提供了高效、可靠的解决方案。消息队列适用于异步任务分发,信号量用于资源同步,共享内存则适合高频数据交换。开发时应根据场景需求选择合适机制,并注意资源释放与同步问题。

- 阅读全文 -

浏览量 : 5665

© 2025 It's Geek KingYoungy. Power By Typecho . Theme by Shiyi

浙ICP备2025160639号  |  浙公网安备33020502001222号

This is just a placeholder img.