美文网首页
思考总结的第一回合

思考总结的第一回合

作者: fooboo | 来源:发表于2018-07-20 22:08 被阅读21次

    这几天在学习leveldb相关的实现,网上的资料挺多的,在分析代码过程中,也参考了一些别的分析文章,这块会在后续总结下这段时间的学习和思考。

    但昨天又回顾了下当时分析的协程实现文章和源码,有些技术点没仔细分析或者不是很明白,今天就总结下。

    关于phxrpc中有处理后响应数据push到dataflow中

    有如下代码:

    100 void EpollNotifier::Notify() {
    101     ssize_t write_len = write(pipe_fds_[1], (void *)"a", 1);
    102     if (write_len < 0) {
    104     }
    105 }
    
    213 void UThreadEpollScheduler::NotifyEpoll() {
    214     if (epoll_wait_events_per_second_ < 2000) {
    216         epoll_wake_up_.Notify();
    217     }
    218 }
    
    443 void Worker::WorkerLogic(void *args, HttpRequest *request, int queue_wait_time_ms) {     
    463     pool_->scheduler_->NotifyEpoll();
    466 }
    

    在工作线程中,当有数据push到dataflow后,调用线程池的NotifyEpoll,然后这里可能会有多个工作线程执行,里面并没有去做临界区工作。在这个实现中,写pipe,只是作为通知,哪怕write不是原子的,最后数据怎么样并不重要,并不使用。然后查了下write是否是原子的,作如下分析引用:
    “对于write(pipefd,buf,nbyte),其要点如下:

    如果nbyte<=PIPE_BUF,不管O_NONBLOCK是否设置,其写操作都是原子的,就是说多个进(线)程都在此条件下同时写同一个管道不会引起数据交错。

    如果nbyte>PIPE_BUF,是不能保证写操作是原子的,写入的数据可能与其他进程写入的数据交错。”

    总结,对于socket这种,一般socket fd交由一个线程负责读写,不会跨线程,不然出现数据包交错等,write文件的话,目前只经历过日志这种,专门由日志线程负责。

    关于O_APPEND模式write的原子性
    Linux命令之write调用的原子性
    write man page
    《Linux 多线程服务端编程》

    关于libco中的一些额外思考总结

    当时分析确实没有想过为什么要这么写,可能是自己没有实际使用经验,纯粹分析技术点,并没有把所有的坑都考虑到。

    libco不像上面或pebble的协程,这里如果使用共享栈,在栈上引用的局部地址/引用,或者变量值,在让出cpu时,拷贝到一个由malloc申请的空间,如果内容原样拷贝回去是不会出现问题的,私有栈也是。这点确实没有像今天这样认真想过。

    还有如果要协程间相互协作,涉及到锁之类的,那线程锁肯定不行吧,是否有协程间的锁呢?或者类似条件变量的,都需要考虑。

    另外还有个,工作线程和IO线程间的通信,有数据push到dataflow时,可能会不停的notify,这块不知是否有优化的地方?比如如果容忍一点误差的话,可以不用加锁的判断queue是否有数据,没有的话则notify等。

    相关文章

      网友评论

          本文标题:思考总结的第一回合

          本文链接:https://www.haomeiwen.com/subject/lhxcmftx.html