服务器编程的注意事项

  • 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()调用。
    可用于并发时跨线程、跨时间传递数据。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值