首页 > 其他分享 >线程同步 死锁

线程同步 死锁

时间:2023-08-30 11:44:04浏览次数:36  
标签:同步 解锁 访问 死锁 加锁 线程 资源

目录

加锁后忘记解锁

// 场景1
void func()
{
    for(int i=0; i<6; ++i)
    {
        // 当前线程A加锁成功, 当前循环完毕没有解锁, 在下一轮循环的时候自己被阻塞了
        // 其余的线程也被阻塞
    	pthread_mutex_lock(&mutex);
    	....
    	.....
        // 忘记解锁
    }
}

// 场景2
void func()
{
    for(int i=0; i<6; ++i)
    {
        // 当前线程A加锁成功
        // 其余的线程被阻塞
    	pthread_mutex_lock(&mutex);
    	....
    	.....
        if(xxx)
        {
            // 函数退出, 没有解锁(解锁函数无法被执行了)
            return ;
        }
        
        pthread_mutex_unlock(&mutex);
    }
}

重复加锁,造成死锁

void func()
{
    for(int i=0; i<6; ++i)
    {
        // 当前线程A加锁成功
        // 其余的线程阻塞
    	pthread_mutex_lock(&mutex);
        // 锁被锁住了, A线程阻塞
        pthread_mutex_lock(&mutex);
    	....
    	.....
        pthread_mutex_unlock(&mutex);
    }
}

// 隐藏的比较深的情况
void funcA()
{
    for(int i=0; i<6; ++i)
    {
        // 当前线程A加锁成功
        // 其余的线程阻塞
    	pthread_mutex_lock(&mutex);
    	....
    	.....
        pthread_mutex_unlock(&mutex);
    }
}

void funcB()
{
    for(int i=0; i<6; ++i)
    {
        // 当前线程A加锁成功
        // 其余的线程阻塞
    	pthread_mutex_lock(&mutex);
        funcA();		// 重复加锁
    	....
    	.....
        pthread_mutex_unlock(&mutex);
    }
}

死锁成环

场景描述:
  1. 有两个共享资源:X, Y,X对应锁A, Y对应锁B
     - 线程A访问资源X, 加锁A
     - 线程B访问资源Y, 加锁B
  2. 线程A要访问资源Y, 线程B要访问资源X,因为资源X和Y已经被对应的锁锁住了,因此这个两个线程被阻塞
     - 线程A被锁B阻塞了, 无法打开A锁
     - 线程B被锁A阻塞了, 无法打开B锁

如何避免

在使用多线程编程的时候,如何避免死锁呢?

  1. 避免多次锁定, 多检查

  2. 对共享资源访问完毕之后, 一定要解锁,或者在加锁的使用 trylock

  3. 如果程序中有多把锁, 可以控制对锁的访问顺序(顺序访问共享资源,但在有些情况下是做不到的),另外也可以在对其他互斥锁做加锁操作之前,先释放当前线程拥有的互斥锁。

  4. 项目程序中可以引入一些专门用于死锁检测的模块

标签:同步,解锁,访问,死锁,加锁,线程,资源
From: https://www.cnblogs.com/liviayu/p/17666832.html

相关文章

  • 初识MQ-同步通讯的优缺点
       ......
  • python多线程
    python多线程多线程threading,利用CPU和IO可以同时执行的原理多进程multiprocessing,利用多核CPU的能力,真正的并行执行任务异步IOasyncio,在单线程利用CPU和IO同时执行的原理,实现函数异步执行使用Lock对资源加锁,防止冲突访问使用Queue实现不同线程/进程之间的数据通信,实现生......
  • leetcode & c++多线程刷题日志
    1.按序打印按序打印解法互斥锁classFoo{mutexmtx1,mtx2;public:Foo(){mtx1.lock(),mtx2.lock();}voidfirst(function<void()>printFirst){printFirst();mtx1.unlock();}voidsecond(function<voi......
  • 多线程|volatile的使用
    一、内存可见性问题先来看如下代码classMyCounter{publicintflag=0;}publicclassThreadDemo22{publicstaticvoidmain(String[]args){MyCountermyCounter=newMyCounter();Threadt1=newThread(()->{while(myCounter.f......
  • DataX数据同步- 不同时间Where条件
    DataX数据同步工具一、介绍:DataX是用来数据同步得第三方工具,能够进行分片,高效得数据同步二、时间自增,根据时间进行数据同步:1.相关截图:  2.where条件处理:主要分为三个数据库的数据同步,不同的处理1.postgresqlreader:ic_shopee_shopperformance"where":"customer_id......
  • nginx同步脚本
    检测nginx进程是否存在异常`#!/bin/bash收集nginx进程pidpid=$(ps-ef|grepnginx|grepworker|awk'{print$2}')收集第一个nginx进程的pid,打上时间戳pid0=$(ps-ef|grepnginx|grepworker|awk'{print$2}'|head-n1)starttime0=$(ps-olstart=-p$pid0)startti......
  • 这是一个基于threading可停止线程的有限容量有限并行度的python任务管理器
    这是一个可停止线程的有限容量有限并行度的任务管理器基于:GitHub-AlitaIcon/StopableThreadJob:可停止线程任务管理器QuickStart基础调用与效果importtimeimportdatetimefromloguruimportloggerfromStopableThreadJob.job_managerimportJobManagerif__name......
  • 数据库同步
    刚开始使用分页的方式同步数据,idasc到2000多万条之后,效率慢了。总结:分页到最后,会越来越慢通过请教大石头大佬,进行了优化大数据同步,一般不用分页的方式,XCode里面是把分页抽取器放在最后的。每次抽取后,下一次用whereid>lastMaxId。你可以参考XCode里面的集中抽取器,最好用的......
  • 深入理解操作系统中进程与线程的区别及切换机制(下)
    前言上一篇文章中我们了解了进程的执行方式,包括早期单核处理器上的顺序执行以及引入多任务概念实现的伪并行。我们还探讨了进程的状态模型。进程可以处于就绪、运行、阻塞和结束等不同的状态。在本篇文章中,我将探讨研究进程的状态模型、控制结构和切换机制。希望通过这篇文章的......
  • 深入探究Java中的多线程并发与同步
    在后端开发中,多线程编程是一项关键技术,能够充分利用多核处理器,提高系统性能和响应能力。然而,多线程编程涉及到并发与同步问题,可能引发复杂的线程安全难题。本篇博客将深入探讨Java中的多线程编程,重点关注并发问题和同步机制。并发与多线程并发是指多个任务在同一时间段内执行,而多线......