c++普通指针无法实现跨进程事件通知,因其仅在进程内有效;必须使用操作系统提供的命名同步原语,如windows的createevent/openevent或linux的sem_open/sem_post。

C++ 无法直接用普通指针实现跨进程事件通知——指针是进程内虚拟地址,跨进程无效。 这是根本限制,不是写法或权限问题。想让两个进程感知同一事件,必须借助操作系统提供的跨进程同步原语。
为什么 raw pointer 在跨进程场景下完全失效
每个进程有独立的虚拟地址空间,0x7fffe8a12345 在进程 A 指向一块堆内存,在进程 B 中这个地址可能映射到只读页、未映射页,甚至触发 SEGFAULT。Windows 的 ReadProcessMemory 或 Linux 的 /proc/pid/mem 也仅限调试/特权场景,且不可用于实时通知。
- 指针值不具备跨进程语义,不携带所有权、生命周期或同步语义
- 即使通过共享内存传递指针值,目标进程解引用时仍会访问自己的地址空间
- 没有原子性保证:写入指针值和读取它之间无同步机制
替代方案:用命名同步对象(Windows)或 POSIX 信号量(Linux)
真正可行的做法是用内核对象做“事件桩”,而非传递地址。例如 Windows 的 CreateEvent 返回句柄,Linux 的 sem_open 返回 sem_t*(该指针指向进程内映射的共享内存段,但语义由内核维护)。
- Windows:用
CreateEvent(NULL, TRUE, FALSE, L"MyApp_Event")创建命名手动重置事件,两进程调用OpenEvent获取同一内核对象句柄 - Linux:用
sem_open("/myapp_event", O_CREAT, 0644, 0)创建命名信号量,sem_post()通知,sem_wait()等待 - 注意:POSIX 信号量需挂载
tmpfs(如/dev/shm),否则sem_open可能失败并返回(sem_t*)-1
共享内存 + 原子标志位(需配合同步原语)
若需传递数据+通知,可组合使用共享内存与同步对象。例如在共享内存中放一个 std::atomic<bool></bool> 标志位,但不能单独依赖它完成通知——因为存在竞态:写端写完标志后,读端可能因 CPU 缓存未刷新而看不到变化。
- 正确做法:先写共享内存数据,再调用
sem_post或SetEvent;读端先sem_wait或WaitForSingleObject,再读共享内存 - Linux 下确保
std::atomic使用memory_order_seq_cst(默认),且共享内存映射为MAP_SHARED - Windows 下若用
CreateFileMapping,需确保所有进程以相同名称打开,且映射视图起始地址无关紧要——内容才是关键
容易被忽略的关键点
很多开发者卡在“为什么我传了地址却收不到”上,其实问题不在代码细节,而在模型错误。最常漏掉的是:
- Linux 下忘记
sem_unlink("/myapp_event")导致重启后sem_open失败(EEXIST) - Windows 下事件对象未设为“跨会话可见”(Session 0 隔离),服务进程无法与桌面进程通信
- 共享内存未设置合理大小或未初始化,导致读端解析出错(如结构体字段错位)
- 把
sem_t*当作普通指针跨进程传递——实际应只传递名字,各进程自行sem_open
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











