死锁及线程与队列之间的等待关系

news2024/11/18 23:22:55

死锁及线程与队列之间的等待关系

  • 死锁及线程与队列之间的等待关系
    • 案例一
    • 案例二
      • 案例三
      • 案例四
      • 案例五
  • 结语

死锁及线程与队列之间的等待关系

我想要补充一下我之前GCD学习中没能理解清楚的死锁及线程与队列之间的等待关系,因为在看锁的博客时,有人给出了一个案例来讲解死锁问题 ;
具体可以看[iOS] 谈谈iOS多线程的锁

在讲解案例前,我想先简单描述一下线程和队列之间的关系 ;
我们可以简单的认为,线程是执行任务的工人 ;队列是管理任务的地方 ;举一个简单的例子 :

NSLog(@"1"); // 任务1
dispatch_sync(dispatch_get_main_queue(), ^{
    NSLog(@"2"); // 任务2
});
NSLog(@"3"); // 任务3

我们执行上面这段代码 ;这里只有主线程这一名工人,这时任务一,dispatch_sync(dispatch_get_main_queue(), ^{
NSLog(@“2”);
});和任务三按顺序添加到主队列中,但执行到dispatch_sync(dispatch_get_main_queue(), ^{
NSLog(@“2”); // 任务2
});时,这时会把块中的任务二添加到主对列中并在任务二执行完之前阻塞主线程,

这一过程如图:
在这里插入图片描述

这时任务3等待任务2执行完解锁主线程,任务2等待任务3进入主线程执行;两者互相等待,从而造成死锁 ;
如果:

NSLog(@"1"); // 任务1
dispatch_async(dispatch_get_main_queue(), ^{
    NSLog(@"2"); // 任务2
});
NSLog(@"3"); // 任务3

这里只有主线程这一名工人,这里只有主线程这一名工人,这时任务一,dispatch_sync(dispatch_get_main_queue(), ^{
NSLog(@“2”);
});和任务三按顺序添加到主队列中,但执行到dispatch_sync(dispatch_get_main_queue(), ^{
NSLog(@“2”); // 任务2
});时,这时会把块中的任务二添加到主对列中,但在任务二执行完之前不会阻塞主线程,所以如图:
在这里插入图片描述

在这里插入图片描述

这个时候我们再来想想串行队列和并行队列以及同步操作和异步操作间的区别 ;

  • 在串行队列中,任务是按照顺序逐个执行的。每个任务完成后,才会从队列中取出下一个任务并执行。在串行队列中,只有一个线程用于执行任务,因此后续的任务必须等待前面的任务完成后才能执行。
  • 当一个任务在串行队列中执行时,它会占用执行该队列的线程。其他任务必须等待该线程空闲下来,才能从队列中取出并执行。所以,在串行队列中,任务是按照顺序执行的,每个任务都需要等待前面的任务完成,即等待执行该任务的线程空闲下来。
  • 与之相反,在并行队列中,多个任务可以并发执行,不需要等待前面的任务完成。并行队列可以拥有多个线程用于执行任务,因此多个任务可以同时从队列中取出并执行,而不必等待其他任务或线程空闲。

串行和并行决定了队列内任务等待关系 ;

  • 同步操作是指在当前线程上执行任务,并且会阻塞当前线程,直到任务完成。当执行同步操作时,代码会按顺序执行,并等待每个操作完成,然后再继续执行下一个操作。同步操作会阻塞当前线程的执行,直到操作完成,因此在同步操作执行期间,当前线程无法做其他事情。
  • 异步操作是指在其他线程上执行任务,不会阻塞当前线程的执行。当执行异步操作时,代码会立即返回,并继续执行后续代码,而不需要等待操作完成。异步操作允许在后台执行任务,提高了程序的响应性能。

同步和异步决定了在线程中执行任务的方式 ;

顺便提醒一下,主线程中默认执行任务都是同步的 ;

串行队列,并行队列,同步,异步简单图示:
在这里插入图片描述

这时再结合我前面讲的理解一下其中的关系

案例一

NSLog(@"1"); // 任务1
dispatch_sync(dispatch_get_main_queue(), ^{
    NSLog(@"2"); // 任务2
});
NSLog(@"3"); // 任务3

执行后:
在这里插入图片描述

这里是一个非常典型的死锁 ;上面讲过了这里就不解释了 ;

案例二

NSLog(@"1"); // 任务1
dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
    NSLog(@"2"); // 任务2
});
NSLog(@"3"); // 任务3

在这里插入图片描述

这里可以看到,主线程完成任务一后,将任务二加入全局队列后阻塞主线程,等待任务二完成后,解锁主线程并完成任务三 ;

案例三

dispatch_queue_t queue = dispatch_queue_create("com.demo.serialQueue", DISPATCH_QUEUE_SERIAL);
NSLog(@"1"); // 任务1
dispatch_async(queue, ^{
    NSLog(@"2"); // 任务2
    dispatch_sync(queue, ^{  
        NSLog(@"3"); // 任务3
    });
    NSLog(@"4"); // 任务4
});
NSLog(@"5"); // 任务5

在这里插入图片描述

主队列中三个任务,执行完任务一后,异步操作将代码块中的三个同步任务插入自定义的串行队列中,这时主线程和线程一都可以执行任务,所以任务二和任务五先后顺序不一定,当queue中取到dispatch。。。。sync时,会阻塞线程一的同时,将代码块中的任务三加到queue尾部,于是任务四和任务三互相等待,造成死锁 ;

在这里插入图片描述

案例四

NSLog(@"1"); // 任务1
dispatch_async(dispatch_get_global_queue(0, 0), ^{
    NSLog(@"2"); // 任务2
    dispatch_sync(dispatch_get_main_queue(), ^{
        NSLog(@"3"); // 任务3
    });
    NSLog(@"4"); // 任务4
});
NSLog(@"5"); // 任务5

下面就不写题解了,和上面差不多 ;
主队列中三个任务,执行完任务一后,异步操作将代码块中的三个同步任务插入自定义的串行队列中,这时主线程和线程一都可以执行任务,所以任务二和任务五先后顺序不一定,当queue中取到dispatch。。。。sync时,会阻塞线程一的同时,将代码块中的任务三加到主队列尾部,这时任务四等待主线程完成任务三后完成

在这里插入图片描述

案例五

dispatch_async(dispatch_get_global_queue(0, 0), ^{
    NSLog(@"1"); // 任务1
    dispatch_sync(dispatch_get_main_queue(), ^{
        NSLog(@"2"); // 任务2
    });
    NSLog(@"3"); // 任务3
});
NSLog(@"4"); // 任务4
while (1) {
}
NSLog(@"5"); // 任务5

在这里插入图片描述

结语

上面这几个例子可以很好的帮助理解线程队列以及任务同步和异步之间的关系,不必去死记这几这者间排列组合的结果 ;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1699706.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何在 Elasticsearch 中选择精确 kNN 搜索和近似 kNN 搜索

作者:来自 Elastic Carlos Delgado kNN 是什么? 语义搜索(semantic search)是相关性排名的强大工具。 它使你不仅可以使用关键字,还可以考虑文档和查询的实际含义。 语义搜索基于向量搜索(vector search&…

Gradient-checkpointing的原理

原文: 将更大的网络安装到内存中。|by 雅罗斯拉夫布拉托夫 |张量流 |中等 (medium.com) 前向传播时,隔几层就保留一层activation数据,其余层的activation都释放掉; 反向传播时,从最近的checkpoint去重新跑forward&…

Docker部署SpringBoot项目(jar包+Mysql)

部署Java项目 项目准备准备Java项目镜像准备配置网络 部署项目细节展示 项目准备 准备Java项目 hmall项目是一个maven聚合项目,使用IDEA打开hmall项目,查看项目结构如图: 我们要部署的就是其中的hm-service,其中的配置文件采用…

前 9 名最佳视频转换器软件完全免费

前 9 名免费视频转换器是什么?在此视频转换器评论中,我们收集了一些有用的提示并列出了顶级免费视频转换器软件,并找出适合所有级别(从初学者到专家)的最佳免费视频转换器。 顶级视频转换器列表 在这一部分中&#xf…

go 爬虫之 colly 简单示例

1. 背景 colly 是 Go 实现的比较有名的一款爬虫框架,而且 Go 在高并发和分布式场景的优势也正是爬虫技术所需要的。它的主要特点是轻量、快速,设计非常优雅,并且分布式的支持也非常简单,易于扩展。 2. 官方文档 https://go-col…

【简单易用,新人友好】一个轻量级生物信息学流程框架,从此解决99%的生物信息学流程搭建问题...

生物信息学数据分析流程的搭建是一项繁重而复杂的工作。随着行业的发展,各种生信流程框架层出不穷,比如有: NextflowSnakemakeCWLWDL 各种标准,各种规则,令人眼花缭乱。选择太多,往往令人无所适从。特别是新进入行业的…

03自动辅助导航驾驶NOP其实就是NOA

蔚来NOP是什么意思?蔚来NOP是啥 蔚来NOP的意思就是NavigateonPilot智能辅助导航驾驶,也就是大家俗称的高阶辅助驾驶,在车主设定好导航路线,并且符合开启NOP条件的前提下,蔚来NOP可以代替驾驶员完成从A点到B点的智能辅助…

<学习笔记>从零开始自学Python-之-实用库篇(一)-pyscript

由Anaconda创建的PyScript是一项实验性的但很有前途的新技术,它使python运转时在支撑WebAssembly的浏览器中作为一种脚本言语运用。 每个现代常用的浏览器现在都支撑WebAssembly,这是许多言语(如C、C和Rust)能够编译的高速运转时…

springboot项目,@Test写法 @Before @After

某文件示例 package cn.xxx.crm.boss;import cn.xxxx.crm.manager.mq.rabbit.AliyunCredentialsProvider; import com.rabbitmq.client.AMQP; import com.rabbitmq.client.Channel; import com.rabbitmq.client.Connection; import com.rabbitmq.client.ConnectionFactory; im…

大模型提示词Prompt学习

引言 关于chatGPT的Prompt Engineer,大家肯定耳朵都听起茧了。但是它的来由?,怎么能用好?很多人可能并不觉得并不是一个问题,或者说认定是一个很快会过时的概念。但其实也不能说得非常清楚(因为觉得没必要深…

x264 码率控制中实现 VBV 算法源码分析

关于 VBV 的解释与原理可以参考x264 码率控制 VBV 原理。 x264中 VBV 算法执行的流程 vbv 参数配置相关函数 x264_param_default函数 功能:编码参数默认设置,关于 vbv的参数的默认设置;函数内vbv相关代码:/* ... */ //代码有删减 param->rc.i_vbv_max_bitrate = 0; par…

《软件方法(下)》8.3.4.3 关于“整体-部分”结构

DDD领域驱动设计批评文集 做强化自测题获得“软件方法建模师”称号 《软件方法》各章合集 8.3 建模步骤C-2 识别类的关系 8.3.4 识别关联关系 8.3.4.2 关联的进一步细分 是否进一步细分各种关联,各种面向对象方法学观点不同。有的认为关联就是关联,…

mvc的常见注解

问文心一言的,记录一下。 PathVariable 路径变量注解 PathVariable 是 Spring MVC 提供的一个注解,它用于从 URI 模板变量中绑定值到控制器方法的参数上。当你在 RequestMapping、GetMapping、PostMapping、PutMapping、DeleteMapping 等注解的 URL 路…

maven默认src下的xml,properties文件不打包到classes文件夹下

一、第一种是建立src/main/resources文件夹,将xml,properties等资源文件放置到这个目录中。maven工具默认在编译的时候,会将resources文件夹中的资源文件一块打包进classes目录中。 这时候注意把resources设置成resource目录,已经…

操作系统 c语言模仿 动态分区存储管理方式的主存分配回收

1.实验目的 深入了解动态分区存储管理方式的主存分配回收的实现。 2.实验预备知识 存储管理中动态分区的管理方式。 3.实验内容 编写程序完成动态分区存储管理方式的主存分配回收的实现。实验具体包括:首先确定主存空间分配表&…

Android 布局中@NULL的使用和代码实现方式详解

文章目录 1、使用场景2、示例代码实现2.1、移除背景2.2 、移除文本2.3、移除布局宽度或高度2.4、移除提示文本2.5、移除图像资源 3、综合示例3.1、布局文件 activity_main.xml3.2、主活动文件 MainActivity.java3.4、资源文件3.5、运行结果 4、优点5、缺点6、综合分析6.1、适用…

地下城游戏(leetcode)

个人主页&#xff1a;Lei宝啊 愿所有美好如期而遇 地下城游戏https://leetcode.cn/problems/dungeon-game/description/ 图解分析&#xff1a; 代码 class Solution { public:int calculateMinimumHP(vector<vector<int>>& vv) {int row vv.size(), col …

【云原生】Kubernetes基础命令合集

目录 引言 一、命令概述 &#xff08;一&#xff09;命令分类 &#xff08;二&#xff09;基本语法 二、查看基本信息 &#xff08;一&#xff09;环境指令 1.查看版本信息 2.查看资源对象简写 3.添加补全信息 4.查看日志 5.查看集群信息 &#xff08;二&#xff0…

5月26号总结

目录 刷题记录(Codeforces Round 947 &#xff08;Div. 1 Div. 2&#xff09;前三题) 1.A. Bazoka and Mochas Array 2.B. 378QAQ and Mochas Array 3.C. Chamo and Mochas Array 刷题记录(Codeforces Round 947 &#xff08;Div. 1 Div. 2&#xff09;前三题) 1.A. Bazok…

力扣 滑动窗口题目总结

Leetcode3.无重复字符的最长子串 思路&#xff1a; 这道题主要用到思路是&#xff1a;滑动窗口 什么是滑动窗口&#xff1f; 其实就是一个队列,比如例题中的 abcabcbb&#xff0c;进入这个队列&#xff08;窗口&#xff09;为 abc 满足题目要求&#xff0c;当再进入 a&#x…