本文共 1116 字,大约阅读时间需要 3 分钟。
setsockopt可以设置各类套接字的一些配置属性。
如: SO_REUSEADDR ——防止服务器重启受阻 SO_REUSEPORT – 开启端口重用,允许多个套接字bind/listen同一个端口 SO_KEEPALIVE – 心跳机制 TCP_NODELAY – 取消Nagle(取消小包合并)CLOEXEC:fork之后写时复制,因此在未写时与父进程共享文件(指向相同)。但如果子进程此时采用exec替换进程,需要在替换之前关闭无用的fd。如果相应的fd非常多,这会很难做到。因此指定fd的flag=CLOEXEC,表示调用exec时关闭该fd。
一个进程的所有线程共享所有信号。
因此,多线程的时候,需要一个线程处理所有信号。 信号处理分散到多个线程中很容易出错。参考14-8-3(linux高性能服务器编程)EPOLLONESHOT
即使使用ET,一个连接fd也可能被触发多次。比如在并发程序中,一个线程读取一次fd进行处理,而此时该fd又有读事件被触发,这时候该fd可能被另一个线程拿到,这就出现了多个线程同时操作同一个连接的情况。 采用EPOLLONESHOT可保证该fd只能被触发一次(因此执行完该事件后,需要重新设置该fd的EPOLLONESHOT,recv=0:对端关闭,recv>0:继续读,recv<0:如果errno==EAGIN,则重置EPOLLONESHOT状态,等待下一次该fd再被epollwait通知)close仅仅让引用减一(因此fork的线程都需要各自进行close),使用shutdown可以真正关闭文件(的读或者写或者读写端)
时间轮,定期执行
时间堆,使用堆顶时间作为下次tick时间,能够实现较精准定时reactor是同步IO,是否阻塞取决于用户配置。proactor是异步IO,
同步IO:用户注册fd,内核通知用户“事件就绪”,用户处理事件。 异步IO:用户注册事件以及对应的事件完成处理函数,内核执行事件,并调用完成处理函数。统一事件源:IO处理(epollwait),信号处理(管道),定时任务(也是信号)等。
信号处理函数不做处理,而是向管道写入信号给主线程,主线程将管道注册到epoll中了,当该信号处理触发epoll时,由主线程执行相关逻辑。 (实际上根据一切皆文件的理念,任意代码都可与某个fd绑定,进而统一事件源进行处理)std::promise与std::future:
promise相当于生产者,future相当于消费者。 future.get()会阻塞等待直到promise.set_value()调用。 可用于并发时跨线程、跨时间传递数据。转载地址:http://wdjzk.baihongyu.com/