zoukankan      html  css  js  c++  java
  • .net 多线程

    一、概念

             什么是线程?线程是程序执行最基本单元,它是一种数据结构。

             百度百科是这样描述的:

             线程,有时被称为轻量级进程(Lightweight Process,LWP),是程序执行流的最小单元。一个标准的线程由线程ID,当前指令指针(PC),寄存器集合和堆栈组成。

             维基百科是这样定义的:

            In computer science, a thread of execution is the smallest sequence of programmed instructions that can be managed independently by a scheduler, which is typically a part of the operating system.[1] The implementation of threads and processes differs between operating systems, but in most cases a thread is a component of a process. Multiple threads can exist within one process, executing concurrently and sharing resources such as memory, while different processes do not share these resources. In particular, the threads of a process share its executable code and the values of its variables at any given time.

           在计算机科学当中,线程是操作系统能够进行调度的最小单位。每个操作系统的线程和进程的实现有所不同,但是大多情况下,线程是进程的一个组件。一个进程中可以有许多线程共存,可并发执行以及共享资源(如内存),而不同进程间不会共享资源,尤其多线程在任何时候可以共享可执行代码,变量值。

           什么是进程?进程是运行中的程序,拥有系统分配的资源。

           百度百科的定义:

           进程(Process)是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。

           维基百科的定义:

            In computing, a process is an instance of a computer program that is being executed. It contains the program code and its current activity. Depending on the operating system (OS), a process may be made up of multiple threads of execution that execute instructions concurrently.[1][2]

           在计算机中,进程是计算机程序执行的实例。它包含程序代码以及当前的活动。依赖于操作系统,一个进程是由多个并行,可执行线程组成的。

    二、线程的分类

          

    三、线程的状态

        

     四、.net中如何开启一个线程

          1、直接new一个Thread,默认是前台线程。由于线程代表了某一类方法的运行,所以得用到委托。我们先看看Thread的构造函数:

    public Thread(ParameterizedThreadStart start)
            {
                if (start == null)
                {
                    throw new ArgumentNullException("start");
                }
                this.SetStartHelper(start, 0);
            }
            
            public Thread(ThreadStart start)
            {
                if (start == null)
                {
                    throw new ArgumentNullException("start");
                }
                this.SetStartHelper(start, 0);
            }

    我们看到Thread构造函数接收 ThreadStart和ParameterizedThreadStart类型的start。那么分别看它们是什么类型:

    public delegate void ParameterizedThreadStart(object obj);
    public delegate void ThreadStart();

    原来一个是带参数的委托,另一个是不带参数的委托。

     2、定义一个Timer

           public Timer(TimerCallback callback)
            {
                int num = -1;
                int num2 = -1;
                StackCrawlMark lookForMyCaller = StackCrawlMark.LookForMyCaller;
                this.TimerSetup(callback, this, (uint) num, (uint) num2, ref lookForMyCaller);
            }
    
            public Timer(TimerCallback callback, object state, int dueTime, int period)
            {
                if (dueTime < -1)
                {
                    throw new ArgumentOutOfRangeException("dueTime", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
                }
                if (period < -1)
                {
                    throw new ArgumentOutOfRangeException("period", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
                }
                StackCrawlMark lookForMyCaller = StackCrawlMark.LookForMyCaller;
                this.TimerSetup(callback, state, (uint) dueTime, (uint) period, ref lookForMyCaller);
            }

    System.Threading.Timer,构造函数接收 TimerCallback 类型,我们看下此类型的定义:

     public delegate void TimerCallback(object state);

    原来是可以传参的委托。

     3、从线程池中取出的线程

         ThreadPool.QueueUserWorkItem

         New Task

     public class Task : IThreadPoolWorkItem, IAsyncResult, IDisposable

     从Task类的定义看,它实现了线程池工作者接口,实现了异步。

     public Task(Action action, System.Threading.CancellationToken cancellationToken) : this(action, null, null, cancellationToken, TaskCreationOptions.None, InternalTaskOptions.None, null)
            {
                StackCrawlMark lookForMyCaller = StackCrawlMark.LookForMyCaller;
                this.PossiblyCaptureContext(ref lookForMyCaller);
            }

    这是它众多构造函数中一个,接收Action类型的委托,cancellationToken为协作式取消线程执行的一个对象。

    Task.Factory.StartNew
    Task.Run

       Task功能非常强大,可参考其它文章理解。

      五、多线程的异步

            异步处理的三个步骤:

                1、启动处理   2、实际处理(比较耗时)   3、任务完成后的处理

                第一步由主线程完成,第二步由子线程完成,第三步如果由主线程完成,那么就牵扯到主线程和子线程之间的同步问题,因为主线程要获取子线程执行的结果,以便完成第三步。如果第三步由子线程完成,那么就可避免这个问题,因为第二步和第三步都由子线程完成,它们是由同一个线程来处理的。

               异步处理需要IAsyncResult,无论是事件,还是委托的Begin、End方法,都是基于IAsyncResult实现的。

      六、多线程的同步

              同步牵扯到对系统资源的竞争或者线程间需要协作完成某些任务。可参考我的其它文章。

  • 相关阅读:
    记一次proc_open没有开启心得感悟
    Nginx 502 Bad Gateway 的错误的解决方案
    Linux安装redis,启动配置不生效(指定启动加载配置文件)
    设置redis访问密码
    LNMP 多版本PHP同时运行
    ***总结:在linux下连接redis并进行命令行操作(设置redis密码)
    设计模式(一)单例模式:3-静态内部类模式(Holder)
    设计模式(一)单例模式:2-懒汉模式(Lazy)
    设计模式(一)单例模式:1-饿汉模式(Eager)
    设计模式(一)单例模式:概述
  • 原文地址:https://www.cnblogs.com/wangqiang3311/p/8530045.html
Copyright © 2011-2022 走看看