C# 多线程编程二

举报
Echo_Wish 发表于 2022/07/04 09:55:09 2022/07/04
【摘要】 C# 多线程编程

多线程基础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();
        }
    }
}

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

举报
请填写举报理由
0/200