于是我再次寻找,发现了eventfd这个神器,在KVM与Qemu的通信之间,eventfd被大牛使用的出神入化,仔细地分析了一下源码,发现这个东西就如名字所说,纯是为了通知而存在的。
作为一个file(linux里有不是file的东西么~~),它的private_data结构体 eventfd_ctx只有可怜的四个变量。
struct eventfd_ctx {
struct kref kref; /* 这个就不多说了,file计数用的,用于get/put */
wait_queue_head_t wqh; /* 这个用来存放用户态的进程wait项,有了它通知机制才成为可能 */
/*
* Every time that a write(2) is performed on an eventfd, the
* value of the __u64 being written is added to "count" and a
* wakeup is performed on "wqh". A read(2) will return the "count"
* value to userspace, and will reset "count" to zero. The kernel
* side eventfd_signal() also, adds to the "count" counter and
* issue a wakeup.
*/
__u64 count; /* 这个就是一个技术器,应用程序可以自己看着办,read就是取出然后清空,write就是把value加上 */
unsigned int flags; /* 所有的file都有的吧,用来存放阻塞/非阻塞标识或是O_CLOEXEC之类的东西 */
};
我之所以选用它是因为它有 eventfd_signal 这个特地为内核态提供的接口,下面的是注释。
* This function is supposed to be called by the kernel in paths that do not
* allow sleeping. In this function we allow the counter to reach the ULLONG_MAX
* value, and we signal this as overflow condition by returining a POLLERR to poll(2).
其实看代码会更清晰一些