C# 多线程并发编程基础

1. 线程基础

1.1 线程简介

C# 中的线程是操作系统能够进行运算调度的最小单位,它被包含在进程中,是进程中的实际运作单位。一个进程可以包含多个线程,这些线程可以并发执行不同的任务。

1.2 线程的创建与启动

在 C# 中,可以使用 System.Threading.Thread 类来创建和管理线程。

创建线程:

Thread thread = new Thread(new ThreadStart(YourMethod));

启动线程:

thread.Start();

1.3 线程的状态

线程在其生命周期中会经历多种状态,包括新建、就绪、运行、阻塞和死亡等。

1.4 线程的优先级

C# 中的线程具有优先级,可以通过 Thread.Priority 属性来设置。优先级高的线程更有可能获得 CPU 时间片。

2. 多线程编程基础

2.1 线程同步

多线程编程中,由于多个线程可能同时访问共享资源,因此需要考虑同步问题。C# 提供了多种同步机制。

锁(Lock):

object lockObject = new object();
lock (lockObject)
{// 临界区代码
}

互斥量(Mutex):

Mutex mutex = new Mutex();
mutex.WaitOne();
// 临界区代码
mutex.ReleaseMutex();

信号量(Semaphore):

Semaphore semaphore = new Semaphore(1, 1);
semaphore.WaitOne();
// 临界区代码
semaphore.Release();

2.2 线程间通信

线程间通信是多线程编程中的重要部分,C# 提供了多种机制来实现线程间的通信。

事件(Event):

ManualResetEvent event = new ManualResetEvent(false);
event.Set(); // 通知其他线程
event.WaitOne(); // 等待其他线程通知

等待句柄(WaitHandle):

AutoResetEvent waitHandle = new AutoResetEvent(false);
waitHandle.Set(); // 通知其他线程
waitHandle.WaitOne(); // 等待其他线程通知

2.3 线程池

线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在后台以异步方式执行任务。

使用线程池:

ThreadPool.QueueUserWorkItem(new WaitCallback(YourMethod));

2.4 异步编程

C# 提供了异步编程模型(Async/Await),可以简化异步操作的编写。

异步方法:

public async Task<int> YourAsyncMethod()
{// 异步操作var result = await SomeAsyncOperation();return result;
}

3. 高级线程管理

3.1 并行类库(TPL)

.NET Framework 4 引入了任务并行库(Task Parallel Library, TPL),用于简化并行编程。

创建任务:

Task task = new Task(YourMethod);
task.Start();

等待任务完成:

Task.WaitAll(task1, task2);

并行循环:

Parallel.For(0, 100, i => 
{// 并行执行的代码
});

3.2 并行 LINQ(PLINQ)

PLINQ 是对 LINQ to Objects 的并行实现,可以显著提高数据处理的性能。

PLINQ 查询:

var query = from num in numbers.AsParallel()where num % 2 == 0select num;

3.3 同步上下文(SynchronizationContext)

同步上下文用于确保在正确的线程上执行回调。

获取当前同步上下文:

SynchronizationContext context = SynchronizationContext.Current;

发布到同步上下文:

context.Post(state => 
{// 在正确的线程上执行的代码
}, state);

4. 线程安全集合

4.1 线程安全集合类

C# 提供了一些线程安全的集合类,可以在多线程环境下安全地使用。

线程安全字典(ConcurrentDictionary):

ConcurrentDictionary<int, string> dict = new ConcurrentDictionary<int, string>();
dict.TryAdd(1, "Value1");
string value;
dict.TryGetValue(1, out value);

线程安全队列(ConcurrentQueue):

ConcurrentQueue<int> queue = new ConcurrentQueue<int>();
queue.Enqueue(1);
int item;
queue.TryDequeue(out item);

4.2 不可变集合

不可变集合是一旦创建就不能修改的集合,可以安全地在多线程间共享。

创建不可变集合:

ImmutableList<int> list = ImmutableList.Create(1, 2, 3);

5. 性能监控与调试

5.1 性能监控

使用性能监控工具可以帮助诊断多线程程序中的性能瓶颈。

性能计数器:

PerformanceCounter counter = new PerformanceCounter("Category", "Counter");
counter.NextValue();

5.2 调试技巧

调试多线程程序需要特殊的技巧和工具。

使用 Visual Studio 调试器:

  • 断点
  • 并行堆栈窗口
  • 并行任务窗口

日志记录:

using (var writer = new StreamWriter("log.txt", true))
{writer.WriteLine("Thread {0} is executing.", Thread.CurrentThread.ManagedThreadId);
}

6. 最佳实践与常见问题

6.1 最佳实践

  • 尽量使用线程池来管理线程
  • 避免过度同步
  • 使用异步编程模型来提高响应性和性能

6.2 常见问题

  • 死锁
  • 竞态条件
  • 线程饥饿

通过遵循最佳实践和了解常见问题,可以编写出高效、稳定的多线程程序。

以上是 C# 多线程并发编程的基础内容,通过掌握这些基本概念和技巧,可以开始编写高效的多线程应用程序。

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

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

相关文章

【Introduction to Reinforcement Learning】翻译解读2

2.2 马尔可夫决策过程&#xff08;MDPs&#xff09; 马尔可夫决策过程&#xff08;MDP&#xff09;为顺序决策提供了框架&#xff0c;其中动作不仅影响即时奖励&#xff0c;还会影响未来结果。与多臂老虎机问题不同&#xff0c;MDP中的即时奖励与延迟奖励相平衡。在多臂老虎机…

STM32单片机入门学习——第22节: [7-2] AD单通道AD多通道

写这个文章是用来学习的,记录一下我的学习过程。希望我能一直坚持下去,我只是一个小白,只是想好好学习,我知道这会很难&#xff0c;但我还是想去做&#xff01; 本文写于&#xff1a;2025.04.07 STM32开发板学习——第22节: [7-2] AD单通道&AD多通道 前言开发板说明引用解…

Python高阶函数-filter

1. 基本概念 filter() 是Python内置的高阶函数&#xff0c;用于过滤序列中的元素。它接收一个函数和一个可迭代对象作为参数&#xff0c;返回一个迭代器&#xff0c;包含使函数返回True的所有元素。 filter(function, iterable)2. 工作原理 惰性计算&#xff1a;filter对象是…

密码学基础——分组密码的运行模式

前面的文章中文我们已经知道了分组密码是一种对称密钥密码体制&#xff0c;其工作原理可以概括为将明文消息分割成固定长度的分组&#xff0c;然后对每个分组分别进行加密处理。 下面介绍分组密码的运行模式 1.电码本模式&#xff08;ECB&#xff09; 2.密码分组链接模式&…

Redlinux(2025.3.29)

1、将你的虚拟机的网卡模式设置为nat模式&#xff0c;给虚拟机网卡配置三个主机位分别为100、200、168的ip地址。(以nmtui命令为例) 2、测试你的虚拟机是否能够ping通网关和dns&#xff0c;如果不能请修改网关和dns的地址。 首先打开虚拟网络编辑器查看NAT设置里的网关IP&…

【PalladiumZ2 使用专栏 1 -- 波形 trigger 抓取详细介绍】

文章目录 Palladium Z2 OverviewPalladium 波形抓取Palladium 波形存放文件创建Palladium Trigger 断点设置Palladium 加探针并 dumpPalladium 波形查看 Palladium Z2 Overview Cadence Palladium Z2 是 Cadence 推出的企业级硬件仿真加速平台&#xff0c;旨在应对复杂 SoC 设…

Redisson分布式锁:原理、使用

1. Redisson简介 Redisson是一个基于Redis的Java客户端库&#xff0c;提供了丰富的分布式对象和服务&#xff08;如分布式锁、信号量、Map等&#xff09;。其核心优势在于​​简化分布式锁的实现​​&#xff0c;并解决了原生Redis分布式锁的常见问题&#xff08;如死锁、误删…

Java大厂面试题 -- JVM 优化进阶之路:从原理到实战的深度剖析(2)

最近佳作推荐&#xff1a; Java大厂面试题 – 深度揭秘 JVM 优化&#xff1a;六道面试题与行业巨头实战解析&#xff08;1&#xff09;&#xff08;New&#xff09; 开源架构与人工智能的融合&#xff1a;开启技术新纪元&#xff08;New&#xff09; 开源架构的自动化测试策略优…

MySQL学习笔记(四)——DML和DQL

目录 1. DML 1.1 添加数据 1.1.1 给指定字段添加数据 1.1.2 给全部字段添加数据 1.1.3 批量添加数据 1.2 修改数据 1.3 删除数据 2. DQL 2.1 基本语法 2.2 基础查询 2.2.1 查询多个字段 2.2.2 字段设置别名 2.2.3 去除重复记录 2.3 条件查询 2.4 聚合函数 2.5 …

DeepSeek-MLA

MLA 结构 需要缓存 KV 向量共用的压缩隐特征K 向量多头共享的带位置编码的向量 为什么带有位置信息的 Q 向量来自于隐特征向量&#xff0c;而带有位置的 K 向量来自于 H 向量且共享呢&#xff1f; 最好的方法肯定是从H向量直接计算并且不共享&#xff0c;但是会大大增加显存使…

检索增强技术RAG和向量数据库技术的优势和劣势,应用范围和价值

RAG 和向量数据库在技术栈中处于不同层级&#xff0c;前者侧重生成任务的准确性与动态性&#xff0c;后者专注检索效率与扩展性。在实际应用中&#xff0c;二者常协同工作&#xff0c;但也可独立服务于不同场景。企业需根据需求选择&#xff1a;若需生成内容&#xff0c;RAG 是…

Python爬虫教程013:使用CrawlSpider爬取读书网数据并保存到mysql数据库

文章目录 3.8 CrawlSpider介绍3.9 CrawlSpider爬取读书网案例3.9.1 创建项目3.9.2 定义要爬取的数据结构3.9.3 获取数据3.9.4 保存数据到本地3.9.5 保存数据到mysql数据库3.9.6 完整项目下载3.8 CrawlSpider介绍 CrawlSpider 是 Scrapy 框架中 最常用的高级爬虫类之一,用于构…

Three.js 系列专题 5:加载外部模型

内容概述 Three.js 支持加载多种 3D 文件格式(如 GLTF、OBJ、FBX),这让开发者可以直接使用专业建模软件(如 Blender、Maya)创建的复杂模型。本专题将重点介绍 GLTF 格式的加载,并调整模型的位置和材质。 学习目标 理解常见 3D 文件格式及其特点。掌握使用 GLTFLoader 加…

P1006 [NOIP 2008 提高组] 传纸条 题解

题目传送门 前言 每次准备摸鱼时都在这道题的界面。 今天有空做做&#xff0c;顺便写一波题解&#xff0c;毕竟估值蹭蹭往下跳。 双倍经验&#xff1a;P1004 [NOIP 2000 提高组] 方格取数&#xff0c;P1006 [NOIP 2008 提高组] 传纸条。 题意简述 现有一个 m m m 行 n …

LLM架构解析:长短期记忆网络(LSTM)(第三部分)—— 从基础原理到实践应用的深度探索

本专栏深入探究从循环神经网络&#xff08;RNN&#xff09;到Transformer等自然语言处理&#xff08;NLP&#xff09;模型的架构&#xff0c;以及基于这些模型构建的应用程序。 本系列文章内容&#xff1a; NLP自然语言处理基础词嵌入&#xff08;Word Embeddings&#xff09…

ffmpeg提取字幕

使用ffmpeg -i test.mkv 获取视频文件的字幕流信息如下 Stream #0:4(chi): Subtitle: subrip (srt) (default) Metadata: title : chs Stream #0:5(chi): Subtitle: subrip (srt) Metadata: title : cht Stream #0:6(jpn)…

Python设计模式:构建模式

1. 什么是构建模式 构建模式&#xff08;Builder Pattern&#xff09;是一种创建型设计模式&#xff0c;它允许使用多个简单的对象一步步构建一个复杂的对象。构建模式通过将构建过程与表示分离&#xff0c;使得同样的构建过程可以创建不同的表示。换句话说&#xff0c;构建模…

使用 VIM 编辑器对文件进行编辑

一、VIM 的两种状态 VIM&#xff08;vimsual&#xff09;是 Linux/UNIX 系列 OS 中通用的全屏编辑器。vim 分为两种状态&#xff0c;即命令状态和编辑状态&#xff0c;在命令状态下&#xff0c;所键入的字符系统均作命令来处理&#xff1b;而编辑状态则是用来编辑文本资料&…

GaussDB回调机制深度实践:从事件驱动到系统集成

GaussDB回调机制深度实践&#xff1a;从事件驱动到系统集成 一、回调机制核心概念 回调类型矩阵 二、核心实现技术栈 触发器回调开发 sql -- 创建审计触发器回调 CREATE OR REPLACE FUNCTION audit_trigger() RETURNS TRIGGER AS $$ BEGININSERT INTO audit_log (operati…

AI小白:AI算法中常用的数学函数

文章目录 一、激活函数1. Sigmoid2. ReLU&#xff08;Rectified Linear Unit&#xff09;3. Tanh&#xff08;双曲正切&#xff09;4. Softmax示例代码&#xff1a;激活函数的实现 二、损失函数1. 均方误差&#xff08;MSE&#xff09;2. 交叉熵损失&#xff08;Cross-Entropy&…