zoukankan      html  css  js  c++  java
  • phtread_mutex 组合

    phtread_mutex通过mutexattr设定其类型,并保存在成员__kind中。pthread_mutex的锁操作函数根据__kind进行方法的分派(dispatch)。__kind由5个字段的位属性组成,其中4个字段可以通过mutexattr进行设定。通过属性的组合来决定锁的功能和行为。

    低4位是基本类型,包括TIMED(有时等待),RECURSIVE(可递归),ERRORCHECK(不可递归),以及ADAPTIVE(有限自旋)。

    这4种类型不能组合使用,最三种包含第一种。不论是设定为RECURSIVE,mutex一样都会记录owner的pid。当检测到递归时,TIMED和ADAPTIVE类型不作处理,会造成死锁。而RECURSIVE则作递归锁处理,ERRORCHECK则视为死锁停止进行锁操作,避免死锁。所以RECURSIVE和ERRORCHECK是两种不同方法对待锁递归可能造成的死锁问题。这4种类型的设定与futex的类型无关。

    假设你已经明白 futex,pi-futex,pthread lowlevellow,rt_mutex。

    <<linux 内核的futex>>

    <<linux 内核的futex pi-support,即pi-futex使用rt_mutex委托>>

    <<pthread的lowlevellock>>

    <<linux 内核的rt_mutex>>

    ROBUST属性字段,mutexattr中的mask为0x40000000,而__kind中的mask为0x4,共1位。锁是否需要额外服务,避免锁的持有线程退出而没有释放,造成其它阻塞线程的死锁问题。依赖robust-futex系统调用,由glibc去维护robust list。当一个线程在获得锁的同时,会将mutex链入到这个线程的robust链表中去。当这个线程没死又释放这个锁的之前,就会将mutex从线程的robust链表中摘除。

    Protocol属性字段,mutexattr中的mask为0x30000000,而__kind中的mask为0x18,共2位。锁是否需要额外服务,避免优先级逆转的问题。对优先级逆转给出了3种处理协议,第一种不处理,第二种采用PI(优先级继承)算法,依赖pi-futex,第三种采用PP(优先级保护),依赖系统调度器提供的调度策略设定系统调用(sched_setscheduler),以及SCHED_FIFO调度策略。

    使用PP协议处理优先级逆转问题时,必须为锁设定一个保护级别的优先级,ceiling。mutexattr中的mask为0x00fff000,而__lock中的mask为0xfff00000,共12位。由于__lock,即futex的高12位被用于存储ceiling,进行PP算法。与robust定义的锁规则不兼容。

    Pshared属性字段,mutexattr中的mask为0x80000000,而__kind中的mask为0x20,共1位。锁是否需要进程间共享,即futex是否放在共享内存。这个属性和futex的地址,在内核中共同标记为一个futex_key。

    elistion属性字段,则没有给出可以设定的接口。由pthread实现库来决定是否实现和使用。

    当一个mutex的属性为0时,它等同于一个lowlevellock。

    除了设定为PI协议的mutex,使用pi-futex,委托锁操作到rt_mutex。其余的使用futex_wait和futex_wake实现锁竞争服务。

    蓝色框是 RECURSIVE 或 ERRORCHECK 的逻辑代码。

    红色框是 PI 或 PP 协议依赖的调用。

    紫色框是 底层的锁服务。

    绿色框是 循环。

    trylock:

    lock:

    unlock:

  • 相关阅读:
    mysql逻辑架构
    delete与truncate的区别
    mycat
    mycat
    MyCat数据库中间件
    mysql主从复制
    docker学习笔记之快速安装
    linux学习笔记之CentOS7系统快速安装
    Redis学习笔记
    双绞线的种类与型号
  • 原文地址:https://www.cnblogs.com/bbqzsl/p/6798381.html
Copyright © 2011-2022 走看看