多线程/任务/同步

多线程的意义

为了解决负载均衡问题,充分利用CPU资源.为了提高CPU的使用率,采用多线程的方式去同时完成几件事情而不互相干扰.为了处理大量的IO操作时或处理的情况需要花费大量的时间等等,比如:读写文件,视频图像的采集,处理,显示,保存等

优点

1.使用线程可以把占据时间长的程序中的任务放到后台去处理

2.用户界面更加吸引人,这样比如用户点击了一个按钮去触发某件事件的处理,可以弹出一个进度条来显示处理的进度

3.程序的运行效率可能会提高

4.在一些等待的任务实现上如用户输入,文件读取和网络收发数据等,线程比较有用

不足

1.如果有大量的线程,会影响性能,因为操作系统需要在它们之间切换.

2.更多的线程需要更多的内存空间

这里需要了解一下这几个概念

并发:Concurrency,逻辑上的同时发生,一个处理器(在不同时刻或者说在同一时间间隔内)"同时"处理多个任务。宏观上是并发的,微观上是按排队等待、唤醒、执行的步骤序列执行。并发性是对有限物理资源强制行使多用户共享(多路复用)以提高效率

并行:物理上的同时发生,多核处理器或多个处理器(在同一时刻)同时处理多个任务。并行性允许多个程序同一时刻可在不同CPU上同时执行

进程:Process,是程序在计算机上的一次执行活动。运行一个程序、启动一个进程。程序是死的(静态的),进程是活的(动态的)。Windows系统利用进程把工作划分为多个独立的区域,每个应用程序实例对应一个进程。进程是操作系统分配和使用系统资源的基本单位。进程包含一个运行-ing应用程序的所有资源、进程(占用的资源)间相互独立

线程:轻量级进程,是进程的一个实体(线程本质上是进程中一段并发运行的代码),执行线程、体现程序的真实执行情况,是处理器上系统独立调度和时间分配的最基本的执行单元。同一进程的所有线程共享相同的资源和内存(共享代码,全局变量,环境字符串等),使得线程间上下文切换更快、可以在同一地址空间内访问内存

C#中可以使用Thread类创建和控制线程,该类允许创建前台线程,以及设置线程的优先级

static void Main(string[] args)
        {
            //创建一个线程
            Thread thread = new Thread(ChildThread1);
            //开始线程
            thread.Start();

            Console.WriteLine("主线程");

            Console.ReadKey();
        }

        public static void ChildThread1()
        {
            Console.WriteLine("子线程_01");
        }

Thread构造函数接收ParameterrizeThreadStart和ThreadStart委托参数,所以也可以这么写

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

注意:线程是由操作系统调度的,每次哪个线程先被执行可以不同,就是说该例子中线程的调度是无序的

lambda表达式结合Thread使用

  var thread2 = new Thread(() => Console.WriteLine("lambda表达式创建主线程"));
      thread2.Start();

给线程传递数据

给线程传递数据可以使用两种方式

  1. 使用带ParameterrizeThreadStart委托参数的Thread构造函数
  2. 创建自定义类.把线程方法定义为实例方法,之后初始化实例数据,启动线程

不带参数

 Thread thread = new Thread(ChildThread1);       
        thread.Start();
public static void ChildThread1()
        {
            Console.WriteLine("子线程_01");
        }

一个参数(ParameterizedThreadStart:由于ParameterizedThreadStart要求参数类型必须为object,所以定义的方法B形参类型必须为object)

 string name = "Wang";
 Thread thread = new Thread(Parameterized);
 thread.Start(name);
public static void Parameterized(object obj)
{
    Console.WriteLine("ParameterizedThreadStart传递参数,参数为{0}", obj);
}

多个参数(自定义类)

class Data
    {
        public string name;
        public int age;
        public Data(string name, int age)
        {
            this.name = name;
            this.age = age;
        }
        public void Write()
        {
            Console.WriteLine("name:{0},age:{1}", this.name, this.age);
        }
    }
var data = new Data("Wang", 24);
Thread thread = new Thread(data.Write);     
       thread.Start();

后台线程

默认情况下:用Thread类创建的线程总是前台线程,线程池中的线程总是后台线程;

前台线程和后台线程的区别在于:

  1. 前台线程:应用程序必须运行完所有的前台线程才可以退出
  2. 后台线程:应用程序可以不考虑其是否已经运行完毕而直接退出,所有的后台线程在应用程序退出时都会自动结束

 前台线程阻止进程的关闭

Thread thread = new Thread(() =>
       {
                Thread.Sleep(5000);
                Console.WriteLine("前台线程执行");
       });
       thread.Start();
       Console.WriteLine("主线程执行完毕");

输出结果:

这里主线程马上执行完成,并不马上关闭,前台线程等待5秒再执行输出

后台线程不阻止进程的关闭

Thread thread = new Thread(() =>
            {
                Thread.Sleep(5000);
                Console.WriteLine("前台线程执行");
            })
            { IsBackground = true };

            thread.Start();
            Console.WriteLine("主线程执行完毕");

输出结果:不等后台线程执行完毕,主线程执行完毕后立即退出

线程优先级

线程控制

线程问题

争用条件:

死锁:

同步:

猜你喜欢

转载自www.cnblogs.com/GnailGnepGnaw/p/10650835.html