C# 多线程实战指南:从线程创建到管理与终止

深入刨析:C#线程优雅终止与窗体安全退出! 在当今软件开发领域,C#语言以其强大的功能和灵活性广受欢迎,尤其是在多线程编程方面。多线程编程能够提高程序的执行效率和响应速度,但同时也带来了线程管理和资源同步的挑战。 阅读详情

多线程是提升 C# 程序并发能力的核心手段,适用于处理耗时操作(如 IO、网络请求、计算密集型任务)。本文从实战角度讲解多线程的创建、管理和优雅终止,全程使用可直接运行的代码示例,贴合新手学习习惯。

前置准备

所有多线程操作都依赖 System.Threading 命名空间,首先在代码中引入:

using System;
using System.Threading;
// 后续用到Task/CancellationToken时需要
using System.Threading.Tasks;

环境要求:.NET Framework 4.0+ / .NET Core 2.0+ / .NET 5+(所有现代 C# 环境均支持)。


一、线程创建:从基础到推荐方式

C# 中创建线程主要有 3 种方式,优先级:Task(推荐)> Thread(基础)> ThreadPool(底层)。

1. 基础方式:Thread 类(无参数)

使用 ThreadStart 委托创建无参数线程,核心方法是 Start() 启动线程。

// 示例:创建无参数线程
class ThreadCreationDemo
{
    static void Main()
    {
        // 1. 定义线程要执行的方法
        void PrintNumbers()
        {
            for (int i = 1; i <= 5; i++)
            {
                // Thread.CurrentThread.ManagedThreadId:获取当前线程ID
                Console.WriteLine($"线程 {Thread.CurrentThread.ManagedThreadId}:数字 {i}");
                // 模拟耗时操作(暂停500毫秒)
                Thread.Sleep(500);
            }
        }

        // 2. 创建线程实例
        Thread thread = new Thread(PrintNumbers);

        // 3. 启动线程(此时线程进入就绪状态,等待CPU调度)
        thread.Start();

        // 主线程继续执行(验证并发)
        Console.WriteLine($"主线程 {Thread.CurrentThread.ManagedThreadId}:我在主线程执行");

        // 等待子线程执行完毕(否则主线程退出会直接结束程序)
        thread.Join();
    }
}

运行结果(线程 ID 可能不同,顺序非固定):

主线程 1:我在主线程执行
线程 3:数字 1
线程 3:数字 2
线程 3:数字 3
线程 3:数字 4
线程 3:数字 5

2. Thread 类(带参数)

使用 ParameterizedThreadStart 委托,参数必须是 object 类型(需手动转换)。

static void Main()
{
    // 带参数的线程方法
    void PrintMessage(object msgObj)
    {
        string message = msgObj as string;
        if (message == null) message = "默认消息";
        
        Console.WriteLine($"线程 {Thread.CurrentThread.ManagedThreadId}:{message}");
        Thread.Sleep(1000);
    }

    // 创建线程并传入参数
    Thread thread = new Thread(PrintMessage);
    // 启动时传入参数
    thread.Start("Hello 多线程!");

    thread.Join();
}

3. 推荐方式:Task(基于线程池,更高效)

Task 是 .NET 4.0+ 推出的现代多线程方案,底层复用线程池,避免手动创建线程的开销,支持异步编程(async/await)。

static void Main()
{
    // 方式1:创建并启动Task
    Task task1 = Task.Run(() => 
    {
        Console.WriteLine($"Task线程 {Thread.CurrentThread.ManagedThreadId}:执行任务1");
        Thread.Sleep(1000);
    });

    // 方式2:带返回值的Task
    Task<int> task2 = Task.Run(() => 
    {
        Console.WriteLine($"Task线程 {Thread.CurrentThread.ManagedThreadId}:执行计算任务");
        Thread.Sleep(1000);
        return 100 + 200;
    });

    // 等待所有Task完成
    Task.WaitAll(task1, task2);
    // 获取带返回值Task的结果
    Console.WriteLine($"计算结果:{task2.Result}");
}

核心优势:Task 自动管理线程生命周期,无需手动调用 Join(可通过 Wait/WaitAll 等待),支持取消、异常捕获等高级特性。


二、线程管理:核心技巧

1. 等待线程完成(Join/Wait)

  • Thread.Join():阻塞当前线程,直到目标线程执行完毕(适用于 Thread 类)。
  • Task.Wait():阻塞当前线程,直到 Task 完成(适用于 Task 类)。
static void Main()
{
    Thread t = new Thread(() => 
    {
        Thread.Sleep(2000);
        Console.WriteLine("子线程执行完毕");
    });
    t.Start();

    Console.WriteLine("等待子线程完成...");
    // 主线程阻塞,直到t执行完毕
    t.Join();
    Console.WriteLine("主线程继续执行");
}

2. 前台/后台线程

  • 前台线程:默认类型,只要有一个前台线程运行,进程就不会退出。
  • 后台线程:进程退出时会强制终止,适合执行非关键任务(如日志收集)。
static void Main()
{
    Thread t = new Thread(() => 
    {
        // 无限循环(验证后台线程行为)
        while (true)
        {
            Console.WriteLine("后台线程运行中...");
            Thread.Sleep(1000);
        }
    });
    // 设置为后台线程
    t.IsBackground = true;
    t.Start();

    // 主线程暂停3秒后退出
    Thread.Sleep(3000);
    Console.WriteLine("主线程退出,进程结束");
}

结果:主线程退出后,后台线程被强制终止,不会无限输出。

3. 线程优先级

通过 Thread.Priority 设置优先级(影响 CPU 调度优先级,不保证执行顺序),可选值:Lowest < BelowNormal < Normal < AboveNormal < Highest。

static void Main()
{
    Thread t1 = new Thread(() => 
    {
        for (int i = 0; i < 5; i++)
        {
            Console.WriteLine("低优先级线程:" + i);
            Thread.Sleep(100);
        }
    });
    t1.Priority = ThreadPriority.Lowest;

    Thread t2 = new Thread(() => 
    {
        for (int i = 0; i < 5; i++)
        {
            Console.WriteLine("高优先级线程:" + i);
            Thread.Sleep(100);
        }
    });
    t2.Priority = ThreadPriority.Highest;

    t1.Start();
    t2.Start();

    t1.Join();
    t2.Join();
}

4. 线程本地存储(ThreadLocal)

解决多线程共享变量的问题,每个线程拥有独立的变量副本:

static void Main()
{
    // 线程本地存储:每个线程有自己的count副本
    ThreadLocal<int> count = new ThreadLocal<int>(() => 0);

    // 启动3个线程,各自累加count
    for (int i = 0; i < 3; i++)
    {
        new Thread(() => 
        {
            for (int j = 0; j < 5; j++)
            {
                count.Value++;
                Console.WriteLine($"线程 {Thread.CurrentThread.ManagedThreadId}:count = {count.Value}");
            }
            // 释放资源
            count.Dispose();
        }).Start();
    }

    Thread.Sleep(2000);
}

三、线程终止:优雅终止而非强制杀死

1. 绝对避免:Thread.Abort()(已废弃)

Abort() 会强制抛出 ThreadAbortException 终止线程,可能导致:

  • 资源泄漏(如未释放文件句柄、数据库连接);
  • 数据损坏(线程执行到一半被终止);
  • .NET Core/.NET 5+ 中已标记为废弃,不推荐使用。

2. 推荐方式1:布尔标志位(简单场景)

通过共享布尔变量控制线程循环,实现优雅终止:

class GracefulStopDemo
{
    // 线程终止标志(必须用volatile,保证多线程可见性)
    private static volatile bool _isStop = false;

    static void Main()
    {
        Thread workerThread = new Thread(Work);
        workerThread.Start();

        // 主线程等待5秒后,触发终止
        Console.WriteLine("5秒后终止子线程...");
        Thread.Sleep(5000);
        _isStop = true;

        workerThread.Join();
        Console.WriteLine("子线程已优雅终止");
    }

    static void Work()
    {
        int count = 0;
        // 循环判断终止标志
        while (!_isStop)
        {
            Console.WriteLine($"子线程运行中,计数:{count++}");
            Thread.Sleep(1000);
        }
        // 终止前的清理工作(释放资源、保存数据等)
        Console.WriteLine("子线程执行清理工作...");
    }
}

关键:volatile 关键字确保多个线程能实时看到变量的最新值,避免缓存导致的判断失效。

3. 推荐方式2:CancellationToken(规范场景)

CancellationToken 是 .NET 官方推荐的取消机制,支持批量取消、注册回调等高级功能,适配 Task/Thread。

static void Main()
{
    // 1. 创建取消令牌源
    CancellationTokenSource cts = new CancellationTokenSource();
    CancellationToken token = cts.Token;

    // 2. 启动线程/Task,传入取消令牌
    Task workerTask = Task.Run(() => 
    {
        int count = 0;
        while (!token.IsCancellationRequested)
        {
            Console.WriteLine($"Task运行中,计数:{count++}");
            Thread.Sleep(1000);
        }
        // 可选:抛出取消异常(符合.NET取消规范)
        token.ThrowIfCancellationRequested();
    }, token);

    // 3. 3秒后触发取消
    Console.WriteLine("3秒后取消Task...");
    Thread.Sleep(3000);
    cts.Cancel(); // 发送取消信号

    try
    {
        workerTask.Wait();
    }
    catch (AggregateException ex)
    {
        // 捕获取消异常(正常流程,无需处理)
        if (ex.InnerException is TaskCanceledException)
        {
            Console.WriteLine("Task已被优雅取消");
        }
        else
        {
            // 处理其他异常
            Console.WriteLine("异常:" + ex.Message);
        }
    }
    finally
    {
        // 释放令牌源资源
        cts.Dispose();
    }
}

优势:支持注册取消回调(token.Register(() => { 清理逻辑 })),适合复杂场景(如多任务批量取消)。


总结

关键点回顾

  1. 创建线程:优先使用 Task(高效、易管理),仅在需精细控制线程(如前台/后台、优先级)时使用 Thread 类。
  2. 管理线程:通过 Join/Wait 等待线程完成,后台线程不会阻塞进程退出,ThreadLocal<T> 解决线程共享变量问题。
  3. 终止线程:绝对避免 Abort(),简单场景用 volatile 布尔标志位,规范场景用 CancellationToken 实现优雅终止,终止前务必执行资源清理。

最佳实践

  • 耗时 IO 操作(如网络请求、文件读写)优先使用 async/await(基于 Task 的异步编程),而非手动创建线程;
  • 计算密集型任务可使用 Task + 线程池,避免创建大量 Thread 导致的资源耗尽;
  • 所有多线程操作需注意线程安全(如锁 lock、原子操作 Interlocked),避免竞态条件。
C# 多线程详细讲解 C# 多线程详细讲解 一、基本概念 1、进程 首先打开任务管理器,查看当前运行的进程: 从任务管理器里面可以看到当前所有正在运行的进程。那么究竟什么是进程呢? 进程(Process)是Windows系统中的一个基本概念,它包含着一个运行程序所需要的资源。一个正在运行的应用程序在操作系统中被视为一个进程,进程可以包括一个或多个线程。 线程是操作系统分配处理器时间的基本单元,在进程中可以有多个线程同时执行代码。进程之间是相对独立的,一个进程无法访问另一个进程的数据(除非利用分布式计算方式),一个进程运行的失败 阅读详情

相关推荐

掌控多线程的命脉:C# 中线程启动、暂停与终止的终极实践

在现代应用程序开发中,如何有效地管理多线程是至关重要的。无论是处理大量并发请求、执行复杂计算,还是异步操作,多线程技术都能极大地提升程序的性能和响应能力。而在 C# 中,线程控制的实现,尤其是启动、暂停、恢复和终止,往往是开发者面对的难题之一。在这篇文章中,我们将深入探讨如何在 C# 中实现线程的精确控制,从而让你在开发中得心应手地“掌控多线程的命脉”。我们将通过具体示例展示如何实现线程的启动、暂停、继续与停止,并讨论常见的多线程控制技巧。

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 1194

C#高级--多线程详解

C#高级–多线程详解 零、文章目录 一、什么是多线程 1、进程 当一个程序开始运行时,它就是一个进程,进程包括运行中的程序和程序所使用到的内存和系统资源。 而一个进程又是由多个线程所组成的。 2、线程 线程是程序中的一个执行流,每个线程都有自己的专有寄存器(栈指针、程序计数器等),但代码区是共享的,即不同的线程可以执行同样的函数。 3、句柄 句柄是Windows系统中对象或实例的标识,这些对象包括模块、应用程序实例、窗口、控制、位图、GDI对象、资源、文件等。 4、多线程 (1)多线程概念 多线程是指程序中

李宥的博客 5万+

C# 多线程窗体应用:如何优雅地终止所有线程

本文深入探讨了C#多线程窗体应用中如何优雅终止所有线程的实践方法。通过对比基础方案如窗体关闭事件处理和Application.Exit的局限性,重点介绍了CancellationToken机制和线程注册表模式等高级解决方案,帮助开发者避免资源泄漏和数据损坏问题,提升应用稳定性。

weixin_29278805的博客 346

C#基础-多线程

闲得蛋疼,整理一下C#线程的基础概念和常规用法。

SchuylerEX的博客 1万+

c#多线程

总结一下同步方法和异步方法的区别:1、同步方法由于主线程忙于计算,所以会卡住界面。异步方法由于主线程执行完了,其他计算任务交给子线程去执行,所以不会卡住界面,用户体验性好。2、同步方法由于只有一个线程在计算,所以执行速度慢。异步方法由多个线程并发运算,所以执行速度快,但并不是线性增长的(资源可能不够)。多线程也不是越多越好,只有多个独立的任务同时运行,才能加快速度。3、同步方法是有序的。异步多线程是无序的:启动无序,执行时间不确定,所以结束也是无序的。

类人_猿的博客 3538

C#.NET多线程编程实战:6个实例深入理解

简介:C#在.NET框架中提供了强大的多线程编程能力,使得开发者能够利用多核处理器进行并行处理。本资源包含了六个涵盖多线程基础和高级特性的C#.NET实例,如线程创建、线程同步与互斥、线程池使用、线程同步原语、异步编程模型、线程通信、线程状态管理、异常处理、线程局部存储和线程优先级等。开发者通过运行和分析这些实例,可以深入学习和掌握C#.NET多线程编程的实战应用。

weixin_31776191的博客 1368

C#【高级篇】 C# 多线程

线程 被定义为程序的执行路径。每个线程都定义了一个独特的控制流。如果您的应用程序涉及到复杂的和耗时的操作,那么设置不同的线程执行路径往往是有益的,每个线程执行特定的工作。 线程是轻量级进程。一个使用线程的常见实例是现代操作系统中并行编程的实现。使用线程节省了 CPU 周期的浪费,同时提高了应用程序的效率。 到目前为止我们编写的程序是一个单线程作为应用程序的运行实例的单一的过程运行的。但是,这样子应用程序同时只能执行一个任务。为了同时执行多个任务,它可以被划分为更小的线程。 ...

星Yeah 的博客 8574

掌握C#多线程:深入原理与STAThread教程

在.NET中,锁是一种常用的同步原语,用于控制多个线程访问共享资源的顺序。锁通常与lock关键字结合使用,确保同一时刻只有一个线程能进入受保护的代码区域。// 只有一个线程能执行此代码块在这个例子中,是作为锁对象。lock关键字在尝试进入代码块之前会锁定这个对象,在退出代码块后会释放锁。需要注意的是,锁定的是对象的引用,而不是对象本身。因此,所有引用都指向同一个对象时才能正确工作。锁的关键特点包括:原子性lock块的执行对于其他尝试进入该块的线程来说是原子操作。

weixin_28487725的博客 788

C# 多线程

一、基本概念 1、进程 首先打开任务管理器,查看当前运行的进程: 从任务管理器里面可以看到当前所有正在运行的进程。那么究竟什么是进程呢? 进程(Process)是Windows系统中的一个基本概念,它包含着一个运行程序所需要的资源。一个正在运行的应用程序在操作系统中被视为一个进程,进程可以包括一个或多个线程。线程是操作系统分配处理器时间的基本单元,在进程中可以有多个线程同时执行代码。进...

1万+

工业场景落地:Java+PaddleOCR实现高性能OCR文字识别的终极方案

本文深度解析基于Java的高性能工业级OCR实现方案,集成PP-OCRv5深度学习模型,提供: ✅ 多场景支持:手写体、竖排文本、票据表格的精准识别 ✅ 工业级性能:毫秒级响应,支持GPU加速与高并发处理 ✅ 开箱即用:通过Maven快速集成,5行代码完成文字识别 ✅ 完整技术栈:覆盖文本检测、方向校正、识别后处理全流程 附可运行示例代码,助您快速构建企业级OCR系统!

deng775747758的博客 3611

LVGL v9的lv_scale控件实战:5分钟打造动态仪表盘(附完整代码)

本文详细介绍了LVGL v9中lv_scale控件的实战应用,通过5个关键步骤快速打造动态仪表盘。文章涵盖核心特性解析、代码实现、样式定制及性能优化,适用于工业HMI、智能家居等场景,并附完整代码示例。

gin88的博客 261

C#:多线程和线程池

一、基本概念 1. 基础   Windows系统是一个多线程的操作系统。         一个程序至少有一个进程,一个进程至少有一个线程。         进程是线程的容器,一个C#客户端程序开始于一个单独的线程,CLR(公共语言运行库)为该进程创建了一个线程,该线程称为主线程。例如当我们创建一个C#控制台程序,程序的入口是Main()函数,Main()函数是始于一个主线程的。它的功能主要...

SSS_369 6493

【大模型】一图看懂3D因果卷积!

本文将系统性地介绍从1D到3D的因果卷积原理,通过直观的动图演示帮助读者理解其工作机制,并重点探讨3D因果卷积在大规模视频生成中的独特价值和应用前景。

xian0710830114的专栏 2197

unity的C#学习——多线程编程(线程的生命周期、创建与管理)与线程相关类

本文介绍了C#当中的多线程编程。除了分析线程类的创建与控制方式,还对线程池、异步编程、同步线程等与线程相关的类做了概念介绍,并列举了一些常用的方法和属性。。

时生的博客 4214

物联网技术-第2章-物联网技术架构

• 物联网具有很强的异构性• 为实现异构设备之间的互联、互通与互操作,物联网需要以一个开放的分层的可扩展的为框架。

m0_73804764的博客 2976

一文掌握 MongoDB 详细安装与配置(Windows / Linux / macOS 全平台)

本文详细介绍了MongoDB社区版7.0+在Windows、Linux和macOS三大操作系统上的完整安装、配置与安全加固流程。主要内容包括:各平台推荐安装方式(Windows使用MSI安装包、Linux通过官方仓库、macOS通过Homebrew)、基本配置参数说明、服务启动方法以及关键安全措施(如创建管理员用户和启用身份验证)。文章还提供了系统最低要求、下载地址、数据目录设置建议以及生产环境使用注意事项,适合开发、测试及生产环境部署参考。

数据知道的博客 6708

C# 多线程处理

一,c#多线程 1、进程 首先打开任务管理器,查看当前运行的进程: 进程(Process)是Windows系统中的一个基本概念,它包含着一个运行程序所需要的资源。一个正在运行的应用程序在操作系统中被视为一个进程,进程可以包括一个或多个线程。线程是操作系统分配处理器时间的基本单元,在进程中可以有多个线程同时执行代码。进程之间是相对独立的,一个进程无法访问另一个进程的数据(除非利用分布式计算...

youandme520的专栏 3756

SAP Fiori Launchpad 上看不到任何 tile 应该怎么办?

中心UI组件是一个框架,为所有SAPFiori应用程序提供公共基础设施SAPFiorilaunchpad是所有SAPFioriUI的基础,并为SAPFiori应用程序提供基本功能,如登录,界面大小,应用程序之间的导航,和基于角色的应用程序目录。ABAP前端服务器包含所有基础设施组件,用于为客户端生成SAPFiori应用程序特定的UI,并与SAPBusinessSuite后端系统通信。SAPFiori应用程序的处理过程如下首先,客户端加载SAPFiori应用程序的界面。...

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 940

C#之多线程与线程池

多线程就是多个线程同时工作的过程,我们可以将线程看作是程序的执行路径,每个线程都定义了一个独特的控制流,用来完成特定的任务。如果您的应用程序涉及到复杂且耗时的操作,那么使用多线程来执行是非常有益的。使用多线程可以节省 CPU 资源,同时提高应用程序的执行效率,例如现代操作系统对并发编程的实现就用到了多线程。到目前为止我们编写的示例程序都是单线程的应用程序,这样的应用程序一次只能执行一个任务。

qq_3517289697的博客 1389

多径衰落信道的 MATLAB 仿真

在无线通信系统中,信号在传输过程中会经历多径传播现象,导致信号在接收端出现时域和频域上的扩展。通过以上示例代码,我们可以进行多径衰落信道的 MATLAB 仿真。同时,我们还可以通过调整信道参数和信号特性,进一步研究多径衰落对系统性能的影响。常用的模型之一是瑞利衰落信道模型,它假设信号在传输过程中受到多个散射路径的影响。除了瑞利衰落信道模型,我们还可以使用其他类型的信道模型,如高斯衰落信道模型。在上述代码中,我们首先定义了信道的参数,包括最大多普勒频移、多径延迟和多径功率衰落。函数来模拟高斯衰落信道。

TechCraze的博客 665

【人工智能之深度学习】12. BERT微调实战:医疗文本分类的领域自适应技巧与工业级实现

摘要:医疗文本分类是自然语言处理在医疗健康领域的核心应用,可辅助疾病诊断、病历结构化和医疗质量监控。然而,医疗文本的专业术语密集、实体关系复杂及数据长尾分布等特性,导致通用BERT模型性能受限。本文系统阐述医疗文本分类的领域自适应技术,从理论原理到工业级实现展开全流程讲解。首先分析医疗文本的独特属性及技术挑战;随后详解领域继续预训练、适配器微调、对抗训练等核心技术的数学原理;构建包含数据预处理、模型优化、隐私保护的完整实战架构;通过疾病分类、情感分析、事件检测三大案例验证技术有效性。

专注于人工智能、软件开发、工控自动化、工厂数字化及智能化等领域,希望和大家共同进步! 1004

C#多线程

C#中的多线程编程是开发高效并发应用程序的关键技术之一,它允许程序同时执行多个任务,从而提升应用程序的响应速度和性能。为了更好地理解C#中的多线程使用和定义,我们可以从以下几个方面来探讨:线程的基本概念、创建线程的方法、线程的状态管理以及线程同步机制。

C6666888的博客 1570

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

C#多线程之旅(七)——终止线程

阅读目录 一、什么时候用Thread.Abort(); 二、Thread.Abort的用法 三、无法终止线程的情形 四、Catch块中抛出异常 五、Finally块中抛出异常 六、Abort调用的时间 先交代下背景,写《C#多线程之旅》这个系列文章主要是因为以下几个原因:1.多线程在C/S和B/S架构中用得是非常多的;2.而且多线程的使用是非常复杂的,如果没有用好,容易造成很多问题。...

sinolover的专栏 5088

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

C#多线程详解

多线程就是多个线程同时工作的过程,我们可以将线程看作是程序的执行路径,每个线程都定义了一个独特的控制流,用来完成特定的任务。在多线程中执行的第一个线程称为主线程,当 C# 程序开始执行时,将自动创建主线程,而使用 Thread 类创建的线程则称为子线程,您可以使用 Thread 类的 CurrentThread 属性访问线程。C# 是通过扩展 Thread 类来创建线程的,然后使用扩展的 Thread 类调用 Start() 方法开始执行子线程。:当线程实例被创建但 Start 方法未被调用时的状况;

这个人好有趣....hh 4153

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

C#多线程中子线程快速终止的几个处理办法

因项目需要,采用了多线程方案,其中主线程负责界面处理(如显示数据、与用户交互等),子线程负责读写串口(发送命令、读取数据)。但是,由于使用多线程的经验较少,对于关闭子线程的问题上走了一些弯路,在此留文纪念,希望能帮助遇到此问题的朋友。          版本1:         在客户关闭程序时,主线程直接关闭,不考虑子线程。        问题:任务管理器中,主程序进程还在运行(在等子线程

EffectiveAgui的专栏 2万+

C# 多线程编程实战(一)--线程基础

C#多线程编程实战(一):线程基础1.1 简介多线程(英语:multithreading),是指从软件或者硬件上实现多个线程并发执行的技术。具有多线程能力的计算机因有硬件支持而能够在同一时间执行多于一个线程,进而提升整体处理性能。具有这种能力的系统包括对称多处理机、多核心处理器以及芯片级多处理(Chip-level multithreading)或同时多线程(Simultaneous multit...

lingshuangcanxue 1万+
上一篇: LINQ 从 0 到 1:完整演变指南(核心术语解析 + 全注释实战)
下一篇: 全面入门 ASP.NET:从 Web Pages 到 MVC 与 Web Forms 的系统教程
bugcome_com
博客等级 码龄3年 32粉丝 131原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

bugcome_com

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值