mach_msg_header_t详解
2026年1月23日 18:01
借助AI能力分析。
mach_msg_header_t - Mach 消息头
作用
这是 Mach 消息的头部结构,用于在 macOS/iOS 的进程间(或线程间)传递消息。
6个字段详解
typedef struct {
mach_msg_bits_t msgh_bits; // 消息标志位
mach_msg_size_t msgh_size; // 消息总大小(字节)
mach_port_t msgh_remote_port; // 目标端口(收信人)
mach_port_t msgh_local_port; // 本地端口(回信地址)
mach_port_name_t msgh_voucher_port; // 追踪端口(调试用)
mach_msg_id_t msgh_id; // 消息ID(自定义)
} mach_msg_header_t;
形象比喻(信封):
| 字段 | 对应信封上的 | 说明 |
|---|---|---|
msgh_remote_port |
收件人地址 | 消息发往哪个端口 |
msgh_local_port |
回信地址 | 如果需要回复,发到这里 |
msgh_size |
信件大小 | 包括信封和内容 |
msgh_bits |
邮寄方式 | 挂号信、平信等 |
msgh_id |
信件编号 | 用于区分不同类型的信 |
msgh_voucher_port |
追踪单号 | 用于追踪和调试 |
在 RunLoop 中的使用
1. 发送唤醒消息(CFRunLoopWakeUp)
// 构造消息头
mach_msg_header_t header;
header.msgh_remote_port = rl->_wakeUpPort; // 发往唤醒端口
header.msgh_local_port = MACH_PORT_NULL; // 不需要回复
header.msgh_size = sizeof(mach_msg_header_t); // 只有头,无内容
header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, 0);
header.msgh_id = 0;
// 发送(唤醒 RunLoop)
mach_msg(&header, MACH_SEND_MSG, ...);
2. 接收消息(RunLoop 休眠)
// 准备缓冲区
uint8_t buffer[3 * 1024];
mach_msg_header_t *msg = (mach_msg_header_t *)buffer;
msg->msgh_local_port = waitSet; // 在哪个端口等待
msg->msgh_size = sizeof(buffer); // 缓冲区大小
// 阻塞等待(线程休眠)
mach_msg(msg, MACH_RCV_MSG, ...);
// 被唤醒后,检查消息来源
if (msg->msgh_local_port == _wakeUpPort) {
// 手动唤醒
} else if (msg->msgh_local_port == _timerPort) {
// 定时器到期
}
关键理解
mach_msg_header_t 是 Mach IPC 的核心:
- 通信基础:所有 Mach 消息都以这个头开始
- 路由信息:指明消息的来源和去向
- RunLoop 休眠/唤醒:通过接收/发送消息实现
完整消息结构:
┌──────────────────────┐
│ mach_msg_header_t │ ← 消息头(必需)
├──────────────────────┤
│ 消息体(可选) │ ← 实际数据
├──────────────────────┤
│ trailer(可选) │ ← 附加信息
└──────────────────────┘
RunLoop 的简化消息:只有头部,无消息体(称为 "trivial message"),足以唤醒线程。