首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

最浅显易懂的一篇:RCU机制

RCU(Read-Copy Update)是数据同步的一种方式,在当前的Linux内核中发挥着重要的作用。RCU主要针对的数据对象是链表,目的是提高遍历读取数据的效率,为了达到目的使用RCU机制读取数据的时候不对链表进行耗时的加锁操作。这样在同一时间可以有多个线程同时读取该链表,并且允许一个线程对链表进行修改(修改的时候,需要加锁)。RCU适用于需要频繁的读取数据,而相应修改数据并不多的情景,例如在文件系统中,经常需要查找定位目录,而对目录的修改相对来说并不多,这就是RCU发挥作用的最佳场景。 Linux内核源码当中,关于RCU的文档比较齐全,你可以在 /Documentation/RCU/ 目录下找到这些文件。Paul E. McKenney 是内核中RCU源码的主要实现者,他也写了很多RCU方面的文章。他把这些文章和一些关于RCU的论文的链接整理到了一起。http://www2.rdrop.com/users/paulmck/RCU/ 在RCU的实现过程中,我们主要解决以下问题: 1,在读取过程中,另外一个线程删除了一个节点。删除线程可以把这个节点从链表中移除,但它不能直接销毁这个节点,必须等到所有的读取线程读取完成以后,才进行销毁操作。RCU中把这个过程称为宽限期(Grace period)。 2,在读取过程中,另外一个线程插入了一个新节点,而读线程读到了这个节点,那么需要保证读到的这个节点是完整的。这里涉及到了发布-订阅机制(Publish-Subscribe Mechanism)。 3, 保证读取链表的完整性。新增或者删除一个节点,不至于导致遍历一个链表从中间断开。但是RCU并不保证一定能读到新增的节点或者不读到要被删除的节点。 宽限期

02
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    RCU 机制_NRPS作用机制

    Read-copy update (RCU) 是一种 2002 年 10 月被引入到内核当中的同步机制。通过允许在更新的同时读数据,RCU 提高了同步机制的可伸缩性(scalability)。相对于传统的在并发线程间不区分是读者还是写者的简单互斥性锁机制,或者是哪些允许并发读但同时不 允许写的读写锁,RCU 支持同时一个更新线程和多个读线程的并发。RCU 通过保存对象的多个副本来保障读操作的连续性,并保证在预定的读方临界区没有完成之前不会释放这个对象。RCU定义并使用高效、可伸缩的机制来发布并读取 对象的新版本,并延长旧版本们的寿命。这些机制将工作分发到了读和更新路径上,以保证读路径可以极快地运行。在某些场合(非抢占内核),RCU 的读方没有任何性能负担。

    02

    Linux文件基础I/O

    1.空文件也要在磁盘占据空间 2.文件 = 内容 + 属性 3.文件操作 = 对内容 + 对属性 4.标定一个文件,必须使用文件路径 + 文件名(唯一性) 5.如果没有指明对应的文件路径,默认是在当前路径进行访问 6.当我们把fopen,fclose,fread,fwrite等接口写完之后,代码编译之后,形成二进制可执行程序之后,但是没运行,文件对应的操作有没有被执行呢?没有 —— 对文件操作的本质是进程对文件的操作。 7.一个文件如果没被打开,可以直接进行文件访问吗??不能!一个文件要被访问,就必须先被打开!(被打开的时候是用户调用端口,操作系统负责操控硬件,所以这个操作是用户进程和操作系统共同完成的) 8.磁盘的文件不是所有的都被打开,是一部分被打开,一部分关闭。 总结:文件操作的本质是进程和被打开文件之间的关系。

    00

    终端I/O---ttyS3: 3 inp

    #include <stdio.h> #include "time.h" #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <termios.h> int main() {   struct termios opt;   int fd=-1;   int nread;   char buf[1024];   fd=open("/dev/ttyS3" ,O_RDONLY    |O_NONBLOCK); if(fd==-1)    {    printf("open /dev/ttyS3 error\n");    }   tcgetattr(fd,&opt);              //获取终端属性到opt   tcflush(fd,TCIOFLUSH);              //同时刷新收到的数据但是不读,刷新写入的数据但是不传送   cfsetispeed(&opt, B9600);                 //设置输入波特率   cfsetospeed(&opt, B9600);             //设置输出波特率   opt.c_cflag&=~CSIZE;              //(不用     )字符长度掩码。取值为 CS5, CS6, CS7, 或 CS8。   opt.c_cflag |=CS8;              //取值为CS8   opt.c_cflag &= ~PARENB;              //(不用     )允许输出产生奇偶信息以及输入的奇偶校验。   opt.c_iflag &= ~INPCK;              //(不用     )启用输入奇偶检测。   opt.c_cflag &= ~CSTOPB;              //(不用     )设置两个停止位,而不是一个   opt.c_cflag &= ~CRTSCTS;              //(不用     )硬件流控   opt.c_cc[VTIME] = 150;              //非 canonical 模式读时的延时,以十分之一秒为单位   opt.c_cc[VMIN] = 0;                      //非 canonical 模式读的最小字符数   opt.c_lflag    &= ~(ICANON | ECHO) ;              //(不用     )启用标准模式 (canonical mode)允许使用              //特殊字符 EOF, EOL, EOL2, ERASE, KILL, LNEXT, REPRINT,               //和 WERASE,以及按行的缓冲。              //(不用     )回显输入字符。   tcflush(fd,TCIOFLUSH);   tcsetattr(fd,TCSANOW,&opt);              //改变立即发生 while(1)     {         nread = read(fd,buf,1000);         //printf("nread=%d\n",nread);         //if(nread !=-1 )    printf("%s",buf);//打印数据         sleep(2);         memset(buf,0x0,1024);     } if(fd!=-1) close(fd);   return 0; }

    01
    领券