长治一般建一个网站需要多少钱,网页翻译脚本,php开发网站建设,大连网站建设微信群一、eventfd
1.1简介#xff1a;
eventfd是进程间通信(IPC)的一种手段#xff0c;主要用来做事件通知。IPC通常方式#xff1a;
1#xff09;unix socket
2#xff09;pipe
3#xff09;共享内存
前两种都是同步调用#xff0c;但是传递大量数据时存在效率问题
eventfd是进程间通信(IPC)的一种手段主要用来做事件通知。IPC通常方式
1unix socket
2pipe
3共享内存
前两种都是同步调用但是传递大量数据时存在效率问题而使用共享内存效率高但是缺乏同步通知机制消费者轮询共享内存修改开销太大。这里可以使用eventfd用来做同步。
1.2 使用
eventfd每次只能发送8个字节的内容(flag)一般用于每个bit表示一个消息类型。
API
1创建文件句柄
#include sys/eventfd.h
int eventfd(unsigned int initval, int flags);2消息发送
// 写 eventfd内部 buffer 必须是 8 字节大小
n write(efd, u, sizeof(uint64_t));3消息接收
// 读 eventfd
n read(efd, u, sizeof(uint64_t));写数据时会累加flag读数据后flag清零。所以这里发送消息时可以同时发送多个消息。
实例
// 写 3 次,发3次消息
write(efd, u /* u 0x01 */ , 8)
write(efd, u /* u 0x02 */ , 8)
write(efd, u /* u 0x04 */ , 8)读数据时会读到累加的数据
read(ebd, x, 8) /*读到x 0x7*/使用场景2
eventfd可以用于进程间信号量的作用生产者每次写入1消费者每次取出1然后执行。不过需要打开选项
EFD_SEMAPHORE (since Linux 2.6.30)Provide semaphore-like semantics for reads from the new file descriptor. Seebelow.查看fd信息
zfjubuntu22:/proc/5686/fd$ ls -l
total 0
lrwx------ 1 zfj zfj 64 5月 19 21:37 0 - /dev/pts/1
lrwx------ 1 zfj zfj 64 5月 19 21:37 1 - /dev/pts/1
lrwx------ 1 zfj zfj 64 5月 19 21:37 2 - /dev/pts/1
lrwx------ 1 zfj zfj 64 5月 19 21:37 3 - anon_inode:[eventfd]eventfd是匿名fd指没有对应具体文件。
实战
eventfd支持poll机制可使用poll和select接口监听。
#include malloc.h
#include pthread.h
#include zconf.h
#include errno.h
#include stdlib.h
#include string.h
#include stdio.h
#include wait.h
#include sys/eventfd.h#define handle_error(msg) \do { perror(msg); exit(EXIT_FAILURE); } while(0)
int main(int argc, char** argv)
{int efd;ssize_t rc;efd eventfd(0, 0);if(-1 efd){handle_error(eventfd);}printf(efd%d\n, efd);int ret fork();uint64_t buf;if (ret 0){/*消费者*/printf(wait for read:\n);rc read(efd, buf, sizeof(uint64_t));printf(read finished: %zd\n, rc);printf(Parent read %llu from efd\n,(unsigned long long)buf);return 0;}else{/*生产者*/buf 0x5;rc write(efd, buf, sizeof(uint64_t));printf(after write\n); }
}
问题
event没有做标识所有进程都只能用同一组系统中只能存在一组eventfd static const struct file_operations eventfd_fops { #ifdef CONFIG_PROC_FS .show_fdinfo eventfd_show_fdinfo, #endif .release eventfd_release, .poll eventfd_poll, .read_iter eventfd_read, .write eventfd_write, .llseek noop_llseek, }; eventfd没有open函数只有一个eventfd的系统调用。
所以仅限于fork出来的进程只能用于主子进程间。
1.3 内核实现
《fs/eventfd.c》
1.4 参考资料
Linux fd 系列 — eventfd 是什么 - 知乎 (zhihu.com)
二、timerfd
2.1 简介
timerfd可用于用户态的定时器定时操作。
2.2 使用
API
// 创建一个 timerfd 句柄
/*clockid
* CLOCK_MONOTONIC开机到现在的时间不可设置的时间
* CLOCK_REALTIME实时时间到时间点执行可重设时间点
*
*/
int timerfd_create(int clockid, int flags);
// 启动或关闭 timerfd 对应的定时器
int timerfd_settime(int fd, int flags, const struct itimerspec *new_value, struct itimerspec *old_value);
// 获取指定 timerfd 距离下一次超时还剩的时间
int timerfd_gettime(int fd, struct itimerspec *curr_value);数据结构
struct timespec64 {time64_t tv_sec; /* seconds */long tv_nsec; /* nanoseconds */
};struct itimerspec64 {/*开始执行后每次间隔多久执行一次*/struct timespec64 it_interval;/*settime后多久开始执行*/struct timespec64 it_value;
};实战
timerfd 绑定的是匿名 inodeeventfd也是匿名inode
#include stdio.h
#include sys/timerfd.h
#include poll.h
#include unistd.h
#include assert.hint main() {struct itimerspec timebuf;int timerfd timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK | TFD_CLOEXEC);/*开始运行后每1s执行一次*/timebuf.it_interval.tv_sec 1;timebuf.it_interval.tv_nsec 0; // period timeout value 1s/*第一次执行设置后5s开始执行*/timebuf.it_value.tv_sec 5;timebuf.it_value.tv_nsec 0; // initial timeout value 5stimerfd_settime(timerfd, 0, timebuf, NULL);struct pollfd fds[1];int len sizeof(fds) / sizeof(fds[0]);fds[0].fd timerfd;fds[0].events POLLIN | POLLERR | POLLHUP;while (1){int n poll(fds, len, -1);for (int i 0; i len n-- 0; i) {if (fds[i].revents POLLIN){unsigned long long val;int ret read(timerfd, val, sizeof(val));if (ret ! sizeof(val)) // ret should be 8{printf(ret bytes instead of 8 frome timerfd\n);break;}printf(timerfd %d timeout\n, timerfd);}}}close(timerfd);return 0;
}2.3 内核实现
static const struct file_operations timerfd_fops { .release timerfd_release,.poll timerfd_poll,.read timerfd_read,.show_fdinfo timerfd_show,// ...
};定时器的poll操作用于定时读操作获取下一次超时剩余时间。
《fs/timerfd.c》
2.4 参考资料
Linux fd 系列 — 定时器 timerfd 是什么 - 知乎 (zhihu.com)