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

Day 02 链锁

《POSIX多线程程序设计》

随意顺序解锁互斥量,不会导致死锁的发生。但在使用“试锁-回退”算法时,应该总以相反的顺序,解锁互斥量。这样有利于,减少线程做回退操作的可能性。

 

链锁及其使用场景

 

链锁

申请多锁的代码示例: 使用backoff 和 yield_flag 命令行参数来调整,增加发生冲突的可能性。

/*************************************************************************
 *  File Name: backoff.c
 *  Created Time: Thu 30 Nov 2017 05:56:18 PM CST
 *************************************************************************/

#include <stdio.h>
#include <pthread.h>
#include <sched.h>
#include "../errors/errors.h"

#define ITERATIONS 10

pthread_mutex_t mutex[3] = {
    PTHREAD_MUTEX_INITIALIZER,
    PTHREAD_MUTEX_INITIALIZER,
    PTHREAD_MUTEX_INITIALIZER
};

int backoff = 1;         /* Whether to backofff or deadlock*/
int yield_flag = 0;        /* 0: no yield, >0: yield, <0: sleep */

void *lock_forward(void *arg)
{
    int i, iterator, backoffs;
    int status;

    for(iterator=0; iterator<ITERATIONS; ++iterator) {
        backoffs=0;
        for(i=0;i<3;i++) {
            if(i==0){
                status = pthread_mutex_lock(&mutex[i]);
                if(status !=0)
                    err_abort(status,"First lock");
            } else {
                if(backoff) {
                    status = pthread_mutex_trylock(&mutex[i]);
                } else
                    status = pthread_mutex_lock(&mutex[i]);

                if(status == EBUSY) {
                    backoffs++;
                    DPRINTF((
                                " [forward locker backing off at %d]\n",i));
                    for(;i>=0;i--) {
                        status = pthread_mutex_unlock(&mutex[i]);
                        if(status != 0)
                            err_abort(status,"backoff");
                    }

                } else {
                    if(status != 0)
                        err_abort(status,"Lock mutex");
                    DPRINTF (("forward locker got %d\n", i));
                }
            }
            if(yield_flag) {
                if(yield_flag > 0)
                    sched_yield();
                else
                    sleep(1);
            }

        }
        printf(
                "lock forward got all locks, %d backoffs\n",backoffs);
        for(i=2;i>=0;i--) {
            pthread_mutex_unlock(&mutex[i]);
        }
        sched_yield();
    }
    return NULL;
}

void *lock_backward(void *arg)
{

    int i, iterator, backoffs;
    int status;

    for(iterator=0; iterator<ITERATIONS; ++iterator) {
        backoffs=0;
        for(i=2;i>=0;i--) {
            if(i==2){
                status = pthread_mutex_lock(&mutex[i]);
                if(status !=0)
                    err_abort(status,"First lock");
            } else {
                if(backoff) {
                    status = pthread_mutex_trylock(&mutex[i]);
                } else
                    status = pthread_mutex_lock(&mutex[i]);

                if(status == EBUSY) {
                    backoffs++;
                    DPRINTF((
                                " [backward locker backing off at %d]\n",i));
                    for(;i<3;i++) {
                        status = pthread_mutex_unlock(&mutex[i]);
                        if(status != 0)
                            err_abort(status,"backoff");
                    }

                } else {
                    if(status != 0)
                        err_abort(status,"Lock mutex");
                    DPRINTF (("backward locker got %d\n", i));
                }
            }
            if(yield_flag) {
                if(yield_flag > 0)
                    sched_yield();
                else
                    sleep(1);
            }

        }
        printf(
                "lock backward got all locks, %d backoffs\n",backoffs);
        for(i=0;i<=2;i++) {
            pthread_mutex_unlock(&mutex[i]);
        }
        sched_yield();
    }
    return NULL;
}

int main(int argc, char *argv[] )
{
    pthread_t forward,backward;
    int status;

    if(argc > 1)
        backoff = atoi(argv[1]);
    if(argc > 2)
        yield_flag = atoi(argv[2]);

    status = pthread_create(
            &forward,NULL,lock_forward,NULL);
    if(status != 0)
        err_abort(status,"create forward");
    status = pthread_create(
            &backward,NULL,lock_backward,NULL);
    if(status != 0)
        err_abort(status,"create backward");

    pthread_exit(NULL);
}

转载于:https://www.cnblogs.com/jfm-cs/p/7930496.html

相关文章:

  • shell基础--变量
  • Hibernate主键生成策略及选择
  • Java集合系列:-----------05LinkedList的底层实现
  • nginx+tomcat单个域名及多个域名配置
  • PV统计优化设计
  • 非常好!讲逻辑回归的,讲得很透彻
  • Redis 分布式锁的正确实现方式
  • 协议适配器错误的问题
  • 2017-2018-1 20155229 《信息安全系统设计基础》第十一周学习总结
  • ORACLE常用数值函数、转换函数、字符串函数
  • MYSQL分表与分区
  • spring security oauth2 authorization code模式
  • 刷新页面清空 input text的值
  • 服务器数据库不用开通远程连接通过工具在本地连接操作的方法
  • 温故·我的笔记
  • 0x05 Python数据分析,Anaconda八斩刀
  • 2017届校招提前批面试回顾
  • Apache Zeppelin在Apache Trafodion上的可视化
  • AWS实战 - 利用IAM对S3做访问控制
  • Docker 笔记(1):介绍、镜像、容器及其基本操作
  • Dubbo 整合 Pinpoint 做分布式服务请求跟踪
  • JavaScript学习总结——原型
  • java架构面试锦集:开源框架+并发+数据结构+大企必备面试题
  • Nginx 通过 Lua + Redis 实现动态封禁 IP
  • php面试题 汇集2
  • ReactNativeweexDeviceOne对比
  • React中的“虫洞”——Context
  • Shell编程
  • webpack4 一点通
  • 前端学习笔记之原型——一张图说明`prototype`和`__proto__`的区别
  • 微服务框架lagom
  • 小李飞刀:SQL题目刷起来!
  • 中国人寿如何基于容器搭建金融PaaS云平台
  • python最赚钱的4个方向,你最心动的是哪个?
  • 阿里云重庆大学大数据训练营落地分享
  • ​草莓熊python turtle绘图代码(玫瑰花版)附源代码
  • # MySQL server 层和存储引擎层是怎么交互数据的?
  • #我与Java虚拟机的故事#连载16:打开Java世界大门的钥匙
  • (pt可视化)利用torch的make_grid进行张量可视化
  • (Redis使用系列) Springboot 使用Redis+Session实现Session共享 ,简单的单点登录 五
  • (编译到47%失败)to be deleted
  • (顶刊)一个基于分类代理模型的超多目标优化算法
  • (附源码)计算机毕业设计SSM保险客户管理系统
  • (附源码)计算机毕业设计SSM疫情下的学生出入管理系统
  • (官网安装) 基于CentOS 7安装MangoDB和MangoDB Shell
  • (九十四)函数和二维数组
  • (亲测有效)解决windows11无法使用1500000波特率的问题
  • (四) Graphivz 颜色选择
  • (一)u-boot-nand.bin的下载
  • (转)AS3正则:元子符,元序列,标志,数量表达符
  • (转)jQuery 基础
  • .desktop 桌面快捷_Linux桌面环境那么多,这几款优秀的任你选
  • .NET Core 2.1路线图
  • .NET 将多个程序集合并成单一程序集的 4+3 种方法
  • .net 托管代码与非托管代码