1、概念

线程 被定义为程序的执行路径。每个线程都定义了一个独特的控制流。如果您的应用程序涉及到复杂的和耗时的操作,那么设置不同的线程执行路径往往是有益的,每个线程执行特定的工作。

线程是轻量级进程。一个使用线程的常见实例是现代操作系统中并行编程的实现。使用线程节省了 CPU 周期的浪费,同时提高了应用程序的效率。

到目前为止我们编写的程序是一个单线程作为应用程序的运行实例的单一的过程运行的。但是,这样子应用程序同时只能执行一个任务。为了同时执行多个任务,它可以被划分为更小的线程。

在C#中,多线程是指在一个应用程序中同时运行多个线程的能力。每个线程代表一个独立的执行路径,可以在同一进程内并发执行。多线程编程允许开发者创建响应性更强、效率更高的应用程序,尤其是在处理I/O密集型任务或需要长时间计算的任务时。

2、线程生命周期

线程生命周期开始于 System.Threading.Thread 类的对象被创建时,结束于线程被终止或完成执行时。

下面列出了线程生命周期中的各种状态:

  • 未启动状态:当线程实例被创建但 Start 方法未被调用时的状况。
  • 就绪状态:当线程准备好运行并等待 CPU 周期时的状况。
  • 不可运行状态:下面的几种情况下线程是不可运行的:
    • 已经调用 Sleep 方法
    • 已经调用 Wait 方法
    • 通过 I/O 操作阻塞
  • 死亡状态:当线程已完成执行或已中止时的状况。
  • 主线程: 当应用程序启动时,一个特殊的线程随之启动,称为主线程或UI线程。在桌面应用程序中,所有用户界面组件都在这个线程上运行。
  • 工作线程: 除了主线程之外的其他线程通常被称为工作线程或后台线程。它们用于执行非UI相关的任务,如数据处理、网络请求等。
  • 并发: 多个线程在同一时间段内交替执行,给人一种同时运行的错觉。
  • 并行: 真正的多个线程同时执行,通常在多核处理器上实现。

3、创建和管理线程

在C#中,可以使用System.Threading.Thread类来创建和管理线程。以下是一个简单的例子:

using System;
using System.Threading; 
 
class Program 
{
    static void Main()
    {
        Thread thread = new Thread(new ThreadStart(DoWork));
        thread.Start(); // 启动线程 
 
        for (int i = 0; i < 10; i++)
        {
            Console.WriteLine("Main thread: Do some work.");
            Thread.Sleep(100); // 模拟工作
        }
 
        thread.Join(); // 等待线程结束 
    }
 
    static void DoWork() 
    {
        for (int i = 0; i < 10; i++)
        {
            Console.WriteLine("Worker thread: Do some work.");
            Thread.Sleep(100); // 模拟工作 
        }
    }
}

在这个例子中,我们创建了一个新的线程来执行DoWork方法。主线程和工作者线程并发执行,输出交错显示。

4、线程同步

多线程编程中的一个重要问题是线程同步,即确保多个线程不会同时访问或修改共享资源,从而避免竞态条件和其他并发问题。C#提供了多种同步机制,包括:

  • lock语句
  • Monitor
  • Mutex
  • Semaphore
  • EventWaitHandle
  • Interlocked

例如,使用lock语句可以确保一段代码块在同一时间只被一个线程执行:

private static object lockObject = new object(); 
 
static void SafeUpdateCounter()
{
    lock (lockObject) 
    { 
        // 更新共享计数器的代码 
    } 
} 

5、高级抽象

随着.NET Framework的发展,出现了更高级别的抽象来简化多线程编程,如:

  • Task Parallel Library (TPL): 提供了一种更简洁的方式来处理并行任务,使用Task类和相关API。
  • Parallel LINQ (PLINQ): 扩展了LINQ,使其支持并行处理。
  • 异步编程模型 (APM): 使用asyncawait关键字,使异步编程更加直观。

6、注意事项

  • 线程开销: 创建和管理线程是有成本的,包括内存和上下文切换的开销。因此,应避免创建过多的线程。
  • 死锁: 不正确的同步可能导致死锁,即两个或多个线程互相等待对方释放资源。
  • 上下文切换: 频繁的上下文切换会降低性能。
  • 调试难度: 多线程程序的调试比单线程程序更复杂。

理解多线程编程的基本原理和挑战对于编写高效、可靠的多线程C#应用程序至关重要。

小白的我,就暂时不用考虑这个,理解,知道这么回事就行。

08-03 05:15