进程,线程,多线程

1、基本概念

什么是进程?html

当一个程序开始运行时,它就是一个进程,进程包括运行中的程序和程序所使用到的内存和系统资源。 而一个进程又是由多个线程所组成的编程

什么是线程?多线程

线程是程序中的一个执行流,每一个线程都有本身的专有寄存器(栈指针、程序计数器等),但代码区是共享的,即不一样的线程能够执行一样的函数异步

什么是多线程?函数

多线程是指程序中包含多个执行流即在一个程序中能够同时运行多个不一样的线程来执行不一样的任务,也就是说容许单个程序建立多个并行执行的线程来完成各自的任务。性能

前台线程后台线程?spa

应用程序的主线程和经过构造一个Thread对象来显式建立的任何线程都默认是前台线程。相反线程池线程默认为后台线程。另外由进入托管执行环境的本机代码建立的任何线程都被标记为后台线程。操作系统

在线程的生命周期中,任什么时候候均可以从前台变为后台,或者从后台变为前台。线程

前台线程能阻止应用程序的终结。一直到全部的前台线程终止后,CLR才能关闭应用程序(即卸载承载的应用程序域)。指针

后台线程(有时也叫守护线程)被CLR认为是程序执行中可作出牺牲的途径,即在任什么时候候(即便这个线程此时正在执行某项工做)均可能被忽略。所以,若是全部的前台线程终止,当应用程序域卸载时,因此的后台线程也会被自动终止。

 

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

 

2、线程的生命周期

 

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

线程生命周期中的各类状态:

未启动状态:当线程实例被建立但 Start 方法未被调用时的情况(将该线程标记为能够运行的状态,但具体执行时间由cpu决定)。

就绪状态:当线程准备好运行并等待 CPU 周期时的情况。

不可运行状态:下面的几种状况下线程是不可运行的:(已经调用 Sleep 方法,已经调用 Wait 方法,经过 I/O 操做阻塞)

死亡状态:当线程已完成执行或已停止时的情况。

 

3、线程

一、主线程

进程中第一个被执行的线程称为主线程

输出:This is MainThread

二、线程的建立

 三、线程的管理

sleep()挂起和Abort() 销毁线程

经过抛出 threadabortexception 在运行时停止线程。这个异常不能被捕获,若是有 finally 块,控制会被送至 finally 块

线程挂起

 

using System;
using System.Threading;
namespace Threading {
    class Program {
        public static void Thread1() {
            Console.WriteLine("Thread1 starts");
            Console.WriteLine("Thread1 Paused for 5 seconds");
            Thread.Sleep(5000);
            Console.WriteLine("Thread1 resumes");
        }
        static void Main(string[] args) {

            var t1 = new Thread(Thread1);
            t1.Start();
            Console.ReadKey();
        }
    }
}

线程销毁代码
using System;
using System.Threading;
namespace Threading {
    class Program {
        public static void Thread1() {
            try {
                Console.WriteLine("Thread1 starts");
                for (int i = 0; i <= 10; i++) {
                    Thread.Sleep(500);
                    Console.WriteLine(i);
                }
                Console.WriteLine("Thread1 Completed");

            } catch (ThreadAbortException ex) {
                Console.WriteLine("Thread1 Abort Exception");

            } finally {
                Console.WriteLine("Couldn't catch the Thread1 Exception");
            }
        }
        static void Main(string[] args) {

            //开启子线程
            var t1 = new Thread(Thread1);
            t1.Start();

            //主线程挂起2s
            Thread.Sleep(2000);
            //终止t1子线程
            t1.Abort();

            Console.ReadKey();

        }
    }
}

 

 

 

4、线程池

在多线程程序中,线程把大部分的时间花费在等待状态,等待某个事件发生,而后才能给予响应咱们通常用ThreadPool(线程池)来解决;线程平时都处于休眠状态,只是周期性地被唤醒咱们使用使用Timer(定时器)来解决。

因为线程的建立和销毁须要耗费必定的开销,过多的使用线程会形成内存资源的浪费,出于对性能的考虑,因而引入了线程池的概念。线程池维护一个请求队列,线程池的代码从队列提取任务,而后委派给线程池的一个线程执行,线程执行完不会被当即销毁,这样既能够在后台执行任务,又能够减小线程建立和销毁所带来的开销。线程池线程默认为后台线程。

线程池自动管理线程线程的建立和销毁。

代码展现:

using System;
using System.Threading;
namespace Threading {

    class Program {
        public static void Thread1(object data) {
            Console.WriteLine("Thread1 => {0}", data.ToString());
        }

        static void Main(string[] args) {

            //控制线程数大小

            //第一个参数是:线程池中辅助线程的最大数目

            //第二个参数是:线程池中异步 I/O 线程的最大数目

            ThreadPool.SetMaxThreads(3, 3);

            for (int i = 0; i < 10; i++) {
                //ThreadPool是静态类无需实例化,
                //ThreadPool.QueueUserWorkItem(new WaitCallback(Thread1), i);
                ThreadPool.QueueUserWorkItem(Thread1, i);
            }
            Console.WriteLine("Thread1 sleep");
            Thread.Sleep(100000);
            Console.WriteLine("Thread1 end");
            Console.ReadKey();
        }
    }
}

 

其实,线程池的启动和终止不是咱们程序所能控制的,线程池中的线程执行完以后是没有返回值的,咱们能够用ManualResetEvent通知一个或多个正在等待的线程已发生事件.

 

http://www.cnblogs.com/yinrq/p/5412238.html

ThreadPool:

https://msdn.microsoft.com/zh-cn/library/system.threading.threadpool.aspx#Y0

ManualResetEvent:

https://msdn.microsoft.com/zh-cn/library/system.threading.manualresetevent.aspx

 

多线程的好处:

能够提升CPU的利用率。在多线程程序中,一个线程必须等待的时候,CPU能够运行其它的线程而不是等待,这样就大大提升了程序的效率。

 

多线程的不利方面:

线程也是程序,因此线程须要占用内存,线程越多占用内存也越多;

多线程须要协调和管理,因此须要CPU时间跟踪线程;

线程之间对共享资源的访问会相互影响,必须解决竞用共享资源的问题;

线程太多会致使控制太复杂,最终可能形成不少Bug;