当前位置: 首页 > news >正文

建设网站的好处和优点台州seo优化公司

建设网站的好处和优点,台州seo优化公司,在手机上建网站,做网站4核是什么意思第四十章 linux-并发解决方法四(顺序锁seqlock) 文章目录第四十章 linux-并发解决方法四(顺序锁seqlock)顺序锁的设计思想是,对某一共享数据读取时不加锁,写的时候加锁。为了保证读取的过程中不会因为写入名…

第四十章 linux-并发解决方法四(顺序锁seqlock)


文章目录

  • 第四十章 linux-并发解决方法四(顺序锁seqlock)


顺序锁的设计思想是,对某一共享数据读取时不加锁,写的时候加锁。为了保证读取的过程中不会因为写入名的出现导致该共享数据的更新,需要在读取者和写入者之间引入一整型变量,称为顺序值sequence。读取者在开始读取前读取该sequence,在读取后再重读该值,如果与之前读取到的值不一致,则说明本次读取作过程中发生了数据更新,读取操作无效,因此要求写入者在开始写入的时候要更新sequence的值。

typedef struct {struct seqcount seqcount;spinlock_t lock;
} seqlock_t;

无符号型整数sequence用来协调读取者与写入者的作spinlock变量lock在多个写入者之间做互斥使用。
程序中如果想静态定义一个seqlock并同时初始化,可以使用DEFINESE_QLOCK宏,该宏会定义一个seqlock_t型变量并初始化其sequence为0,lock为0:

#define __SEQLOCK_UNLOCKED(lockname)            \{                        \.seqcount = SEQCNT_ZERO(lockname),    \.lock =    __SPIN_LOCK_UNLOCKED(lockname)    \}
#define DEFINE_SEQLOCK(x) \seqlock_t x = __SEQLOCK_UNLOCKED(x)

如果要动态初始化一个seqlock变量,可以使用seqlock_init:

#define seqlock_init(x)                    
do {                        
seqcount_init(&(x)->seqcount);        
spin_lock_init(&(x)->lock);        
} while (0)

下面看看写入者在seqlock上的上锁操作write_seqlock:

static inline void write_seqlock(seqlock_t *sl)
{spin_lock(&sl->lock);write_seqcount_begin(&sl->seqcount);
}
static inline void write_seqcount_begin(seqcount_t *s)
{write_seqcount_begin_nested(s, 0);
}
static inline void write_seqcount_begin_nested(seqcount_t *s, int subclass)
{raw_write_seqcount_begin(s);seqcount_acquire(&s->dep_map, subclass, 0, _RET_IP_);
}
static inline void raw_write_seqcount_begin(seqcount_t *s)
{s->sequence++;smp_wmb();
}

写入者在对写之前需要先获得seqlock上的自旋锁lock,这说明在写入者之间必须保证互斥操作,如果某一写入者成功获得lock。那么需要史新sequence的值以便让其他写入者知道共享数据发生了更新。写入者与写入者之间并不需要sequence。

static inline void write_sequnlock(seqlock_t *sl)
{write_seqcount_end(&sl->seqcount);spin_unlock(&sl->lock);
}
static inline void write_seqcount_end(seqcount_t *s)
{seqcount_release(&s->dep_map, 1, _RET_IP_);raw_write_seqcount_end(s);
}
static inline void raw_write_seqcount_end(seqcount_t *s)
{smp_wmb();s->sequence++;
}

主要的工作是释放自旋锁lock,至于写入者对sequence的更新,主要是用来告诉读取者有数据更新发生,所以必须确保sequence的值在写入的前后发生变化。在此基础上sequence提供的另外一个信息是写入过程有没有结束,这是用sequence的最低位来完成的,如果sequence & 0为0表明写入过程己经结束,否则表明写入过程正在进行·接下来会在读取者的seqlock作数中看到sequence的这两种用途。
某一写入者可以使用write_tryseqlock来保证在无法获得lock时不让自己进入自旋状态(当然也就无法更新数据)而直接返回0,成功获得锁则返回1:

读取者在读取开始前需要先调用read_seqbegin函数,该函数主要用来返回读取开始之前的sequence值:

static inline unsigned read_seqbegin(const seqlock_t *sl)
{return read_seqcount_begin(&sl->seqcount);
}
static inline unsigned read_seqcount_begin(const seqcount_t *s)
{seqcount_lockdep_reader_access(s);return raw_read_seqcount_begin(s);
}
static inline unsigned raw_read_seqcount_begin(const seqcount_t *s)
{unsigned ret = __read_seqcount_begin(s);smp_rmb();return ret;
}

s

tatic inline unsigned __read_seqcount_begin(const seqcount_t *s)
{unsigned ret;repeat:ret = READ_ONCE(s->sequence);if (unlikely(ret & 1)) {cpu_relax();goto repeat;}return ret;
}

从函数的实现也可以看出,如果当前正好有写入者在进行写操作,那么该函数将不停循环直到写过程结束,前面曾提到sequence最低位的用途,这里正好是其实际使用的地方。另一方面,从读取者对写入过程结束的孤环等待可以看出,写入者的实际写入操作占用的时间不应太长。
内核还给读取者提供了一个read_seqretry函数,与read_seqbegin的返回值一起使用,来判定本次的读取操作是否有效:

static inline unsigned read_seqretry(const seqlock_t *sl, unsigned start)
{return read_seqcount_retry(&sl->seqcount, start);
}
static inline int read_seqcount_retry(const seqcount_t *s, unsigned start)
{smp_rmb();return __read_seqcount_retry(s, start);
}
static inline int __read_seqcount_retry(const seqcount_t *s, unsigned start)
{return unlikely(s->sequence != start);
}

函数的参数是读取者在读取操作之前调用read_seqbegin获得的初始值。如果本次读取无效(读取过程中发生了数据更新),那么readq返回1,否则返回0。下面分别给出写入者和读取者利用上面介绍的seqlock函数进行数据读/写协调的例子:

//定义一个全局的seqlock变量demo_seqlock
DEFINE_SEQLOCK(demo_seqlock);//对于写入者的代码
...
//实际写之前调用write_seqlock获取自旋锁,同时更新sequence的值
write_seqlock(&demo_seqlock);
//获得自旋锁之后调用do_write进行实际的写入操作
do_write();
//写入结束,调用write_sequnlock释放锁
write_sequnlock(&demo_seqlock);//对于读取者的代码
unsigned start;
do{//读操作前鲜活的sequence的值start,用以在读操作结束时判断数据是否发生更新//注意读操作无需获得锁start = read_seqbegin(&demo_seqlock);//调用do_read进行实际操作do_read();
}while(read_seqretry(&demo_seqlock,start));//如果数据有更新,再重新读取

如果考虑到中断安全的问题,可以使用读取者与写入者的对应版本:

void write_seqlock_irq(seqlock_t *sl)
void write_seqlock_bh(seqlock_t *sl)
write_seqlock_irqsave(lock, flags)
void read_seqlock_irq(seqlock_t *sl)
void read_seqlock_bh(seqlock_t *sl)
read_seqlock_irqsave(lock, flags

前面曾讨论过读取者与写入者自旋锁rwlock,对比这里的seqlock.会发现两者非常相似。不同之处在于seqlock在写的时候只与其他写入者互斥,而rwlock在写的时候与读取者和写入者都互斥·因此当要保护的资源很小很简单,会很频繁被访问并且写入操作很少发生且必须快速时,就可以使用seqlock。

http://www.hkea.cn/news/991242/

相关文章:

  • 秭归网站建设网站seo优化心得
  • wordpress电影网站模板seo运营
  • 公司注册网上核名业务如何终止网站排名优化怎么做
  • 网站建设伍金手指下拉2网上推广平台
  • 沧州网站建设公司翼马爱情链接
  • 计算机学了出来干嘛免费优化推广网站的软件
  • 宁波网站建设优化湖南seo优化按天付费
  • 门户网站手机版google官网入口
  • 深圳市工程建设交易服务中心网站软文什么意思
  • 大型网架加工厂成都网站建设方案优化
  • 导航网站的广告怎么做的千锋教育官方网
  • etc网站开发票网站制作软件免费下载
  • 上海seo网站设计2022十大网络营销案例
  • 还有做网站的必要吗网站运营推广方案
  • 企业营销型网站建设厂家品牌搜索引擎服务优化
  • 学校网站建设计划怎么成为百度推广代理商
  • 普陀网站开发培训学校seo快速优化
  • 建一个商城网站多少钱免费的网站推广软件
  • 手机网站解决方案看网站搜什么关键词
  • 顺企网江西网站建设宜昌今日头条新闻
  • 坪山网站建设行业现状网页设计与制作代码成品
  • 网站建设需求文档模板下载学大教育一对一收费价格表
  • 小型网站怎样优化百度首页官网
  • 网站开发与iso9001关系百度上做推广怎么做
  • wordpress怎么设置导航镇江seo
  • 番禺建设网站服务软文写作网站
  • 有哪些专做自然风景图片的网站石首seo排名
  • 移动网站虚拟主机seo 排名 优化
  • 专业网站建设课程网站推广优化方式
  • 适合站长做的网站信息流广告投放工作内容