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

C#中多线程编程中的同步、异步、串行、并行及并发及死锁

在C#中,多线程编程是一个强大的功能,它允许程序同时执行多个任务。然而,这也带来了复杂性,特别是在处理同步、异步、串行、并行、并发以及死锁等问题时。下面我将详细解释这些概念,并给出一些C#中的示例和注意事项。

目录

1. 同步(Synchronous)

2. 异步(Asynchronous)

3. 串行(Serial)

4. 并行(Parallel)

5. 并发(Concurrency)

6. 死锁(Deadlock)

结论


1. 同步(Synchronous)

在同步编程中,任务的执行顺序是线性的,即一个任务完成后,下一个任务才会开始。C#中的同步方法会阻塞调用线程,直到方法执行完成。

示例

void SynchronousMethod()
{// 执行一些操作Thread.Sleep(1000); // 模拟耗时操作Console.WriteLine("SynchronousMethod 完成");
}

2. 异步(Asynchronous)

异步编程允许任务在后台执行,而不会阻塞调用线程。在C#中,asyncawait关键字用于实现异步编程。

示例

async Task AsynchronousMethod()
{// 等待异步操作完成await Task.Delay(1000); // 模拟耗时操作Console.WriteLine("AsynchronousMethod 完成");
}

3. 串行(Serial)

串行执行意味着任务按照顺序一个接一个地执行,这在单线程程序中是自然的。

// 同步串行
void Task1()
{Console.WriteLine("Task 1 is running");
}void Task2()
{Console.WriteLine("Task 2 is running");
}Task1();
Task2();// 异步串行
async Task Task1Async()
{Console.WriteLine("Task 1 is running");await Task.Delay(1000); // 模拟异步操作
}async Task Task2Async()
{Console.WriteLine("Task 2 is running");await Task.Delay(1000); // 模拟异步操作
}async Task MainAsync()
{await Task1Async();await Task2Async();
}MainAsync().GetAwaiter().GetResult(); // 运行异步方法

4. 并行(Parallel)

并行执行允许多个任务同时执行,通常利用多核处理器的能力。在C#中,Parallel.ForParallel.ForEachParallel.Invoke等API用于并行执行。

示例

using System.Threading.Tasks;void Task1()
{Console.WriteLine("Task 1 is running");
}void Task2()
{Console.WriteLine("Task 2 is running");
}Parallel.Invoke(() => Task1(), () => Task2());
Parallel.For(0, 10, i =>
{Console.WriteLine($"并行任务 {i} 开始");Thread.Sleep(100); // 模拟耗时操作Console.WriteLine($"并行任务 {i} 完成");
});

5. 并发(Concurrency)

并发是并行和串行在更广泛意义上的结合。它指的是多个任务同时或几乎同时执行,但不一定在物理上并行(可能由于时间片轮转而在单核处理器上模拟并行)。

using System.Threading;void Task1()
{Console.WriteLine("Task 1 is running");
}void Task2()
{Console.WriteLine("Task 2 is running");
}Thread t1 = new Thread(new ThreadStart(Task1));
Thread t2 = new Thread(new ThreadStart(Task2));t1.Start();
t2.Start();t1.Join();
t2.Join();

6. 死锁(Deadlock)

死锁是多线程编程中常见的问题,当两个或多个线程相互等待对方释放资源时,就会发生死锁。这会导致这些线程永远无法继续执行。

死锁发生的四个必要条件:

互斥条件:指进程对所分配到的资源进行排它性使用,即在一段时间内某资源只由一个进程占用。如果此时还有其它进程请求资源,则请求者只能等待,直至占有资源的进程用毕释放。

请求和保持条件:指进程已经保持至少一个资源,但又提出了新的资源请求,而该资源已被其它进程占有,此时请求进程阻塞,但又对自己已获得的其它资源保持不放。

不剥夺条件:指进程已获得的资源,在未使用完之前,不能被剥夺,只能在使用完时由自己释放。
环路等待条件:指在发生死锁时,必然存在一个进程——资源的环形链,即进程集合{P0,P1,P2,···,Pn}中的P0正在等待一个P1占用的资源,P1正在等待P2占用的资源,……,Pn正在等待已被P0占用的资源

避免死锁的策略

  • 确保所有线程以相同的顺序获取资源。

  • 使用锁超时机制。

  • 避免嵌套锁。

  • 使用更高级的并发控制机制,如信号量、事件或Concurrent集合。

示例(可能导致死锁):

object lock1 = new object();
object lock2 = new object();void Thread1Method()
{lock (lock1){Thread.Sleep(100); // 模拟耗时操作lock (lock2){// 执行一些操作}}
}void Thread2Method()
{lock (lock2){Thread.Sleep(100); // 模拟耗时操作lock (lock1){// 执行一些操作}}
}

在这个例子中,如果Thread1MethodThread2Method几乎同时执行,并且都尝试先锁定lock1lock2(但顺序相反),那么它们可能会相互等待对方释放锁,从而导致死锁。

结论

在C#中进行多线程编程时,需要仔细考虑同步、异步、串行、并行和并发的问题,以及如何避免死锁等并发问题。合理使用asyncawaitParallel类、锁(如lock语句)以及Concurrent集合等,可以帮助你编写高效且稳定的多线程程序。

相关文章:

C#中多线程编程中的同步、异步、串行、并行及并发及死锁

在C#中,多线程编程是一个强大的功能,它允许程序同时执行多个任务。然而,这也带来了复杂性,特别是在处理同步、异步、串行、并行、并发以及死锁等问题时。下面我将详细解释这些概念,并给出一些C#中的示例和注意事项。 …...

【Lampiao靶场渗透】

文章目录 一、IP地址获取 二、信息收集 三、破解SSH密码 四、漏洞利用 五、提权 一、IP地址获取 netdiscover -i eth0 Arp-scan -l Nmap -sP 192.168.78.0/24 靶机地址:192.168.78.177 Kali地址:192.168.78.128 二、信息收集 nmap -sV -p- 192.…...

使用WebSocket实现log日志流的实时展示-从轮询到通知

场景介绍 最近开发一个系统,其中一个模块需要展示实时的执行过程,过程日志可能比较多。以前的方案都是前端定时轮询,比如每秒查一次后端接口,将拉取回来的日志重新展示。轮询方案简单容易实现,但是比较消耗资源&#…...

UE5 从零开始制作跟随的大鹅

文章目录 二、绑定骨骼三、创建 ControlRig四、创建动画五、创建动画蓝图六、自动寻路七、生成 goose八、碰撞 和 Physics Asset缺点 # 一、下载模型 首先我们需要下载一个静态网格体,这里我们可以从 Sketchfab 中下载:Goose Low Poly - Download Free …...

O’Reilly

--江上往来人,但爱鲈鱼美。 --君看一叶舟,出没风波里。 OReilly OReilly出版社出版的技术类图书 俗称动物系列 应该是每个技术人员的必备手册。 OReilly动物系列(中译本) 简介" 动物系列作为 OReilly 书籍的典型代表被普遍…...

优盘驱动器未格式化:数据拯救行动指南

优盘困境:驱动器未格式化的挑战 在日常的数据存储与传输中,优盘以其便携性和高容量成为了我们不可或缺的伙伴。然而,当您尝试访问优盘时,突然弹出的“驱动器未被格式化”提示却如同晴天霹雳,让人措手不及。这一状况不…...

4.Handler mappings

处理程序映射 简介 在早期版本的 Spring 中,用户需要在 Web 应用程序上下文中定义一个或多个 HandlerMapping bean 以将传入的 Web 请求映射到适当的处理程序。随着注解控制器的引入,通常不再需要这样做,因为 RequestMappingHandlerMapping…...

《学会 SpringMVC 系列 · 消息转换器 MessageConverters》

📢 大家好,我是 【战神刘玉栋】,有10多年的研发经验,致力于前后端技术栈的知识沉淀和传播。 💗 🌻 CSDN入驻不久,希望大家多多支持,后续会继续提升文章质量,绝不滥竽充数…...

深度学习项目 -7-使用 Python 的手写数字识别

一、前言 该文章仅作为个人学习使用 二、正文 项目源代码:深度学习项目 - 使用 Python 进行手写数字识别 - DataFlair (data-flair.training) 数据集:​​​​​​​https://drive.google.com/open?id1hJiOlxctFH3uL2yTqXU_1f6c0zLr8V_K Python 深…...

MySQL —— 库,数据类型 与 表

库与基础操作 1.1 查看数据库 使用 show databases; 可以查看当前 MySQL 目前有多少个数据库 5 rows 表示有 5 行,这里是表示的是有效的数据,不包括 第一行的指引 set 表示结果集合 0.01 sec 表示这个 sql 语句一共运行了0.01 秒,一般情况…...

Java重修笔记 第二十七天 匿名内部类

匿名内部类 1. 定义:无类名(底层自动分配类名“外部类名$1”),既是类也是对象,定义在外部类的局部位置,例如方法体和代码块中,通过new类或接口并在大括号里重写方法来实现。 2. 使用场景&…...

Nero Lens 智图 - 适用于 iOS 和 iPadOS 的专业图片处理 App

首先是手机端的无损放大 App:Nero Lens 智图,适用于 iOS 和 iPadOS,不仅可以放大,还有多种 AI 图片增强功能。 使用这款 App 可以通过 AI 模型智能放大可达 400%,还有老照片去划痕、上色,抠图移除背景、照…...

Nginx代理路径被吃

Nginx代理路径被吃的情况 日常工作中经常使用nginx反向代理一些资源,有时正常代理,发现代理不过去。 验证被吃调location情况 通过浏览器访问: https://zhao138969.com/LinuxPackage/Python/SelectDocker location /LinuxPackage { proxy…...

pytest-html报告修改与汉化

前言 Pytest框架可以使用两种测试报告,其中一种就是使用pytest-html插件生成的测试报告,但是报告中有一些信息没有什么用途或者显示的不太好看,还有一些我们想要在报告中展示的信息却没有,最近又有人问我pytest-html生成的报告&a…...

react-native从入门到实战系列教程一Swiper组件的使用及bug修复

轮播图,在app中随处可见,这么重要的功能我们怎么可能不学习下在react-native中的实现方式。 依然是第三方组件react-native-swiper 官网地址 https://www.npmjs.com/package/react-native-swiper 组件使用的组件及事件参考官方即可。 实现效果 官网…...

springboot开发的常用注解总结-配置组件类注解

Spring Boot 提供了许多注解,这些注解大大简化了 Spring 应用的配置和开发过程。以下是一些常见的 Spring Boot注解及其作用。 目录 配置组件类 (Configure Component )Configuration解释:Demo Code:更深度使用&#x…...

DataX 最新版本安装部署

1、下载 git clone gitgithub.com:alibaba/DataX.git 2、打包 mvn -U clean package assembly:assembly -Dmaven.test.skiptrue...

【架构】应用保护

这篇文章总结一下应用保护的手段。如今说到应用保护,更多的会想到阿里的sentinel,手段丰富,应用简单。sentinel的限流、降级、熔断,可以自己去试一下,sentinel主要通过配置实现功能,不难。sentinel的简介放…...

从核心到边界:六边形、洋葱与COLA架构的深度解析

文章目录 1 引言2 软件架构3 架构分类4 典型的应用架构4.1 分层架构4.2 CQRS4.3 六边形架构4.4 洋葱架构4.5 DDD 5 COLA架构设计5.1 分层设计5.2 扩展设计5.3 规范设计5.3.1 组件规范5.3.2 包规范5.3.3 命名规范 6 COLA架构总览7 小结 1 引言 软件的首要技术使命:管…...

04-Fastjson反序列化漏洞

免责声明 本文仅限于学习讨论与技术知识的分享,不得违反当地国家的法律法规。对于传播、利用文章中提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,本文作者不为此承担任何责任,一旦造成后果请自行承担&…...

Vim 调用外部命令学习笔记

Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...

装饰模式(Decorator Pattern)重构java邮件发奖系统实战

前言 现在我们有个如下的需求,设计一个邮件发奖的小系统, 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其…...

《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》

引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...

JavaScript 中的 ES|QL:利用 Apache Arrow 工具

作者:来自 Elastic Jeffrey Rengifo 学习如何将 ES|QL 与 JavaScript 的 Apache Arrow 客户端工具一起使用。 想获得 Elastic 认证吗?了解下一期 Elasticsearch Engineer 培训的时间吧! Elasticsearch 拥有众多新功能,助你为自己…...

python/java环境配置

环境变量放一起 python: 1.首先下载Python Python下载地址:Download Python | Python.org downloads ---windows -- 64 2.安装Python 下面两个,然后自定义,全选 可以把前4个选上 3.环境配置 1)搜高级系统设置 2…...

uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖

在前面的练习中,每个页面需要使用ref,onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入,需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...

【第二十一章 SDIO接口(SDIO)】

第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...

深入理解JavaScript设计模式之单例模式

目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式(Singleton Pattern&#…...

CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云

目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...

浅谈不同二分算法的查找情况

二分算法原理比较简单,但是实际的算法模板却有很多,这一切都源于二分查找问题中的复杂情况和二分算法的边界处理,以下是博主对一些二分算法查找的情况分析。 需要说明的是,以下二分算法都是基于有序序列为升序有序的情况&#xf…...