Linux系统调用是否提供获取/释放语义?eventfd读写语义及文档查询
eventfd读写操作的内存一致性语义问题
问题1:eventfd的读写操作是否提供获取/释放语义?
是的,eventfd的write()和read()操作分别提供release和acquire语义:
- 调用
write()向eventfd写入时,会确保调用前所有内存修改(比如示例中线程1的g_atomic_val = 1)被同步到内存,后续被唤醒的线程通过read()读取eventfd后,能看到这些修改。 - 调用
read()读取eventfd时,会确保读取操作完成后,后续的内存访问能看到所有在对应write()之前完成的修改。
对应你的示例代码,线程2中的assert(g_atomic_val == 1)永远不会触发,线程2必然能看到线程1对g_atomic_val的赋值。
问题2:是否有相关文档说明此事?
虽然eventfd(2)的手册页没有直接明确标注这一点,但Linux下所有用于线程同步的文件描述符操作(包括eventfd、epoll、futex相关接口)都遵循统一的内存一致性规则:这类同步操作的唤醒/通知机制自带acquire/release语义,和你提到的futex_wake/futex_wait、epoll_ctl/epoll_wait等行为一致。
这类语义是Linux同步机制的通用约定,确保线程间通过同步原语传递数据时的内存可见性,你可以参考Linux内核文档中关于内存屏障和同步原语的设计说明来进一步确认。
示例代码
initial: int g_atomic_val = 0; int evfd = eventfd(); int64_t w_cnt = 1, r_cnt; thread1: /* set some data, then write eventfd */ g_atomic_val = 1; write(evfd, &w_cnt, sizeof(w_cnt)); thread2: for (;;) { /* polling event fd */ poll(evfd); read(evfd, &r_cnt, sizeof(r_cnt)); /* Does g_atomic_val always equals to 1? */ assert(g_atomic_val == 1); }
内容的提问来源于stack exchange,提问作者Leander
相关产品推荐
相关产品推荐

