多线程基础02

    科技2022-08-14  88

    多线程基础02

    对锁而言,尽可能得使用父对象(级别更大得对象内容)。

    通知

    通知

    是指一个线程告诉另一个线程等待另一个线程回馈结果的操作。

    如果没有得到反馈该线程会一直等待,直到另一个线程反馈为止。

    通知一般使用Join方法,也可以使用同步类对象

    同 步 基 元说 明Monitor监视器,支持锁定操作,防止一个或多个线程同时访问资源Mutex互斥器,支持锁定操作,防止一个或多个线程同时访问资源ReaderWriterLock读写锁,支持锁定操作,定义支持单个写线程和多个读线程的锁Semaphore信号量,也叫信号灯,阻塞线程直到另一个线程信号通知AutoResetEvent事件类,支持通知同步,阻塞线程直到另一个线程设置事件ManualResetEvent事件类,支持通知同步,阻塞线程直到另一个线程设置事件

    同步类对象

    AutoResetEvent 类

    通知正在等待的线程已发生事件

    提供一种通知机制,可以控制线程执行的先后顺序

    AutoResetEvent 类/ManualResetEvent类的重要方法

    方 法说 明Set设置并发送信号Reset重置信号,也就是使信号无效WaitOne等待一个信号,如果没有信号到来则等待ManualResetEvent.WaitAny静态方法,等待一个信号数组,信号数组里面有任何信号到都可以,否则等待ManualResetEvent.WaitAll静态方法,等待一个信号数组,信号数组里面的信号全部到齐才可以,否则等待

    创建AutoResetEvent对象

    AutoResetEvent myResetEvent = new AutoResetEvent(false);

    参数说明:

    false表示事件开始是无信号状态,

    当参数为true表示创建的事件开始是有信号的,就相当于使用false参数创建事件后立即调用了Set方法。

    俗称信号灯

    orderEvent.WaitOne() //等待信号,一直等

    orderEvent.Set() //发出信号,等待的子线程执行

    线程池

    现状

    创建和销毁线程代价高

    线程池

    线程池是系统自己维护的线程的集合。

    线程池技术减少频繁的线程创建与销毁对系统性能的影响

    对于每一个进程系统都会给其创建一个线程池

    如果想要执行线程操作,只需要向线程池发出一个执行某个操作的请求即可。

    CLR线程池

    •1) 最小线程数,线程池的线程总大于等于这个值,一般这个值设置为逻辑CPU数,也就是能充分利用CPU同时执行这些线程。

    •2) 最大线程数,默认1000,不建议修改这个值,如果这个值过小,很可能运行的线程的都被阻塞,而排队的线程永远得不到执行。

    •3) 线程池是非常智能的,并不会发现可用线程不够马上创建新的线程,而是会有一个延迟以确保真的需要新的线程来补充(因为也不建议线程池中的方法执行时间太长比如超过500毫秒,影响线程池的判断)。线程池的目的就是减少实际线程的创建和回收,重复利用线程来做不同的工作。

    ThreadPool

    线程池静态类

    托管线程池中的线程为后台线程,即它们的 IsBackground 属性为 true。这意味着在所有的前台线程都已退出后,ThreadPool 线程不会让应用程序保持运行。

    向线程池提交任务:

    原型: static bool QueueUserWorkItem( WaitCallback callBack, Object state )

    举例: WaitCallback callBackCheck=new WaitCallback(this.Check); ThreadPool.QueueUserWorkItem(callBackCheck,info);

    参数WaitCallback原型 委托 public delegate void WaitCallback (Object state);

    线程池的一些重要知识

    ThreadPool中的Thread不能手动取消,也不用手动开始。所以ThreadPool并不适用比较长的线程。只需要把一个 WaitCallback委托塞给ThreadPool,然后剩下的工作将由系统自动完成。系统会在ThreadPool的线程队列中一一启动线程。

    当线程池满时,多余的线程会在队列里排队,当线程池空闲时,系统自动调入排队的线程,以保持系统利用率。

    当需要复杂的同步技术,例如事件,或需要对一个线程调用Join方法时线程池就不能满足需求了.

    以下情况中不宜使用ThreadPool而应该使用单独的Thread: 1.需要为线程指定详细的优先级 2.线程执行需要很长时间 3.需要前台线程。 4.在线程执行中需要对线程操作,如打断,挂起等

    总结

    进程和线程相关概述

    进程就是一个正在执行的应用程序。是系统进行资源分配的基本单位。

    线程是在进程的内部执行的指令序列,共享进程的内存和系统资源。

    多线程编程概述

    v**.Net****下如何创建线程**

    Thread

    线程的不同状态

    ThreadState

    线程同步技术

    加锁:lock,monitor

    通知:AutoResetEvent

    线程池

    类的扩展方法的简单使用:

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.IO.Ports; using System.Runtime.CompilerServices; namespace day31test03 { class Program { /// <summary> /// 扩展方法 /// </summary> /// <param name="args"></param> static void Main(string[] args) { //SerialPort port = new SerialPort(); Test test = new Test(); test.ddd(4, 5); test.add(4, 5); } } class Test { public void add(int a, int b) { Console.WriteLine(a+b); } } static class T { public static int ddd(this Test t, int x, int y) { return 2*(x - y); } } }

    并行的多线程,让CPU多个核都能跑起来。

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace day31test05 { class Program { /// <summary> /// 并行的多线程 /// 多任务 /// </summary> /// <param name="args"></param> static void Main(string[] args) { Action action = new Action(Dowork); System.Threading.Tasks.Task task = new Task(action); task.Start(); Action action1 = new Action(Dowork); System.Threading.Tasks.Task task1 = new Task(action1); task1.Start(); Console.Read(); } public static void Dowork() { do { } while (true); } } }

    匿名方法委托,并行for和foreach

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace day31test06 { class Program { /// <summary> /// 基于匿名方法的多线程 /// 避免了委托 /// </summary> /// <param name="args"></param> static void Main(string[] args) { /*System.Threading.Thread t3 = new System.Threading.Thread(a => { Console.WriteLine("基于匿名方法的多线程"); }); t3.Start();*/ //并行for,特点:快 //System.Threading.Tasks.Parallel.For(0, 100, a => { System.Threading.Thread.Sleep(100); Console.WriteLine(System.DateTime.Now); }); //并行foreach,特点: String[] str = { "1" , "s", "w"}; System.Threading.Tasks.Parallel.ForEach(str, (item, kk) => { Console.WriteLine(item); }); Console.Read(); } } }
    Processed: 0.019, SQL: 8