读简化版reactor.c代码:
(1)将 epfd 全局定义,为什么不能定义在main()里面?
答:之所以在代码中把 epfd 定义为全局变量,是因为多个函数都需要访问它,定义到main()里就无法直接访问epfd。
(2)eoll_ctl()里的参数EPOLL_CTL_ADD和EPOLL_CTL_DEL直观的表示fd的增加的删除,但EPOLL_CTL_MOD是什么意思?它怎么用?
答:用来更新之前通过 EPOLL_CTL_ADD 注册的事件。就是说EPOLLIN和EPOLLOUT都是内核自己已经判断好的,而EPOLL_CTL_MOD会更新内核的这个判断,而再往后才是epoll_wait提取这个结果。
(3)“typedef int (*RCALLBACK)(int fd);”为什么要自定义这个类型?
答:RCALLBACK 是通过 typedef 定义的函数指针类型。用于指向返回值为 int 且参数为 int 的函数。在代码中用于注册不同的回调函数,以应对不同的事件(例如 accept、recv 和 send)。这种设计符合 回调机制 的思想。
(4)memcy是个怎样的函数?为什么要有这个?不通过memcpy就不可以把数据复制给另一个函数吗?
答:这个2个问题,a)是memcpy用法;b)是参数在不同函数间的传递。
a)直接使用 = 赋值语句不会发生实际的内存内容复制,比如
wbuffer = rbuffer; // 这只是将 wbuffer 指向 rbuffer 内存,而不是复制内容
只是让 wbuffer 和 rbuffer 指向同一块内存区域(即指针相等),并不会将 rbuffer 中的数据复制到 wbuffer 中。而 memcpy 可以确保 rbuffer 和 wbuffer 互相独立,rbuffer 存储了收到的数据,而 wbuffer 则是准备发送的缓存区。
b)一个函数 A 中定义的参数,只能在函数 A 内部使用,如果你希望将这个参数传递给函数 B,需要显式地将其作为参数传递给函数 B,比如
void A(int x) {
// 这里的x是A函数内部的参数
printf("In A: %d\n", x);
B(x); // 将A函数中的参数x传递给B函数
}
void B(int y) {
// 这里的y是B函数内部的参数
printf("In B: %d\n", y);
}
或者使用使用全局变量,比如
int global_var; // 全局变量
void A() {
global_var = 5; // 在A函数中修改全局变量的值
}
void B() {
printf("In B: %d\n", global_var); // 在B函数中访问全局变量
}
int main() {
A();
B(); // A函数修改了global_var,B函数可以读取
return 0;
}