C# 多线程编程

news2025/1/11 17:54:14

1 线程与进程

 进程进程可以理解为一块包含了某些些资源的内存区域,操作系统通过进程这一方式把他的工作划分为不同的单元。一个应用程序可以对应于多个进程。

线程:线程是进程中的独立执行单元, 对于操作系统而言,他通过调度线程来使应用程序工作。一个进程中至少包含一个线程,该线程称为主线程。

线程和进程之间的关系可以理解为:线程是进程中的执行单元,操作系统通过调度线程来使应用程序工作;而进程则是线程的容器,他由操作系统创建,又在具体的执行过程中创建了线程。

线程是由操作系统负责调度

同时线程具有优先级:一共具有7个不同的优先级别

线程有前后台之分:主线程一直都是前台线程,同时我们可以使用Thread类来创建前台线程。

using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace 多线程02
{
    class Program
    {
        static void Main(string[] args)
        {
            Thread parmThread = new Thread(new ParameterizedThreadStart(Worker));
            parmThread.Name = "线程1";
            parmThread.Start("123");
            Console.WriteLine("从主线程返回");
        }

        private static void Worker(object data)
        {
            Thread.Sleep(1000);
            Console.WriteLine("传入的参数为:"+data.ToString());
            Console.WriteLine("从线程1返回");
            Console.Read();
        }
    }
}

 二 线程池

线程池是指用来存放应用程序中要使用的线程集合,你可以理解为一个存放线程的地方,这种集中存放的方式有利于对线程进行管理。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading;
namespace 线程池01
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("主线程ID={0}", Thread.CurrentThread.ManagedThreadId);
            ThreadPool.QueueUserWorkItem(CallBackWorkItem);
            ThreadPool.QueueUserWorkItem(CallBackWorkItem, "work");
            Thread.Sleep(3000);
            Console.WriteLine("主线程退出");
        }

        private static void CallBackWorkItem(object state)
        {
            Console.WriteLine("线程池开始执行");
            if (state != null)
            {
                Console.WriteLine("线程池线程ID={0} 传入的参数为{1}", Thread.CurrentThread.ManagedThreadId, state.ToString());
            }
            else
            {
                Console.WriteLine("线程池线程ID={0}", Thread.CurrentThread.ManagedThreadId);
            }
        }
    }
}

三 线程同步

线程同步技术存在的意义在于:确保某一时刻只有一个线程再操作共享资源。多线程应用程序可以调高程序的性能,但是当我们创建多个线程后,可能会出现一种情况,即多个线程同时去访问某一个共享资源,这将损坏资源中所保存的数据,因此,我们需要使用到线程同步技术。

使用监视器对象(Monitor)能够确保线程拥有对共享资源的互斥访问权。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace 线程同步01
{
    class Program
    {
        static int tickets = 100;
        static object gloalObj = new object();//辅助对象
        static void Main(string[] args)
        {
            Thread thread1 = new Thread(SaleTicketThread1);
            Thread thread2 = new Thread(SaleTicketThread2);
            thread1.Start();
            thread2.Start();
        }

        private static void SaleTicketThread1()
        {
            while (true)
            {
                try
                {
                    Monitor.Enter(gloalObj);//在 object对象上获得排他锁
                    Thread.Sleep(1);
                    if (tickets>0)
                    {
                        Console.WriteLine("线程1出票:", + tickets--);
                    }
                    else
                    {
                        break;
                    }
                }
          
                finally
                {
                    Monitor.Exit(gloalObj);//释放排他锁
                }
            }
        }

        private static void SaleTicketThread2()
        {
            while (true)
            {
                try
                {
                    Monitor.Enter(gloalObj);//在 object对象上获得排他锁
                    Thread.Sleep(1);
                    if (tickets > 0)
                    {
                        Console.WriteLine("线程2出票:", + tickets--);
                    }
                    else
                    {
                        break;
                    }
                }

                finally
                {
                    Monitor.Exit(gloalObj);//释放排他锁
                }
            }
        }
    }
}

四 线程同步存在的问题

在设计应用程序时,应尽量比卖你使用线程同步,它存在一些问题:

1 使用繁琐:使用过程中需要加锁和释放锁,麻烦

2 影响程序性能:加锁和释放锁需要时间,并且决定哪个线程线获取锁的时候,CPU需要进行协调,同样需要时间。

3 回导致线程阻塞:多线程中,线程同步每次只允许一个线程访问资源,导致系统回创建更多的线程,CPU的调度工作会越发的繁重。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/416506.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【学习笔记】unity脚本学习(四)【inputManager、键盘输入、鼠标输入、Raycast】

目录输入inputManagerHorizontal虚拟轴的各个属性含义(摘选自ChatGpt,部分回答不准确)键值的含义键名称命名约定:键盘输入静态函数GetKeyGetButtonKeyCodeGetButton/Down/upGetAxisGetAxisRaw 返回由 axisName 标识的虚拟轴的值&a…

【Gradle-2】一文搞懂Gradle配置

1、前言 “Gradle的配置太多了,经常版本更新还有变化,而且它还能扩展,记是记不住了,只能用到再搜了,哎,难顶” 真的难顶,但是我想挑战一下… 本文介绍的重点: Gradle配置简介Grad…

slam与导航开发

Gmapping是一种基于激光雷达数据的地图构建算法,可以用于建立机器人的环境地图。 Gmapping算法是基于粒子滤波器(Particle Filter)的SLAM算法,它通过将机器人在环境中的位姿和地图中的特征进行联合估计,实现了机器人在…

个人使用mac OS和win OS的差异

苹果 macOS 操作系统和 Windows 操作系统在很多方面有所不同,主要体现在以下几个方面: 用户界面:macOS 和 Windows 的用户界面风格不同。macOS 推崇简洁、优雅的设计,注重操作体验;Windows 软件更为丰富,但…

Doris(1):Doris介绍

1 Doris简介 Apache Doris是一个现代化的基于MPP(大规模并行处理)技术的分析型数据库产品。简单来说,MPP是将任务并行的分散到多个服务器和节点上,在每个节点上计算完成后,将各自部分的结果汇总在一起得到最终的结果(…

最小生成树和最短路径及其他

还是学过的,主要用于复习q v q 一、最小生成树 最小生成树的定义 用于无向图中,无向图指的是没有带方向路径的图,给定n个点,m条边,如果将这些点依次相连,求出连接这些点的最小数值 应用场景 根据这个算…

9 个JSON.stringify的秘密大多数开发人员却不知道

作为前端开发工程师,你一定用过JSON.stringify,但你知道它的全部秘密吗? 很久以前,我因此在工作中犯下了无法挽回的错误。如果我早点知道,就不会发生这样的悲剧。 理解 JSON.stringify 基本上,JSON.stri…

神经网络辐射场NeRF、实时NeRF Baking、有向距离场SDF、占用网络Occupancy、NeRF 自动驾驶

1 NeRF原理2 NeRF加速PlenoxelsKiloNeRFInstant NGPTensoRF3 SDF NeRF4 Occupancy NeRF5 NeRF应用简介常见应用实际应用的挑战6 NeRF自动驾驶1 NeRF原理 NeRF (Neural Radiance Fields,神经辐射场) 是2020年ECCV会议上的Best Paper,其将隐式表达推上了…

安卓玩机搞机----移植第三方rom修复 第三方GSI系统修复bug综合解析【一】

很多朋友热衷与刷写第三方非当前机型官方系统的rom。和刷写第三方gsi等等。例如 米系列机型刷写Flyme 一加机型刷写miui oppo刷写gsi等等。 很多友友也会尝试自己移植第三方rom。但此类操作最大的问题在于修复可以开机后的bug,今天的教程综合说明下这类修复思路…

STM32F103RCT6

STM32F103RCT6是一款由STMicroelectronics公司生产的基于ARM Cortex-M3内核的32位微控制器。 它具有高性能、低功耗和广泛的应用领域。 包括ADC(模数转换器) DAC(数字模拟转换器) TIM(定时器) USART&#x…

Python 中 SyntaxError: ‘yield‘ outside function 错误

当我们在函数外部使用 yield 关键字时,会出现 Python “SyntaxError: ‘yield’ outside function”。 要解决该错误,如果我们需要对每个元素执行一些运算符,请使用列表理解,或者缩进函数内部使用 yield 的代码。 下面是一个产生…

Maven(四):Maven的使用(中)

Maven(四):Maven的使用(中)前言一、实验四:创建 Maven 版的 Web 工程1、说明2、操作3、生成的pom.xml4、生成的Web工程的目录结构5、创建 Servlet5.1 在 main 目录下创建 java 目录5.2 在 java 目录下创建 …

【从零开始学Skynet】实战篇《球球大作战》(六):gateway代码设计(中)

1、编码和解码 我们来实现两个辅助方法str_unpack和str_pack,用于消息的解码和编码。 (1)str_unpack代码 local str_unpack function(msgstr)local msg {}while true dolocal arg, rest string.match( msgstr, "(.-),(.*)")if…

TCP/IP协议及配置

文章目录一、TCP/IP概述1. TCP/IP协议族2. 主机与主机之间通信的三个要素二、什么是IP地址1. 用来标识一个网络节点的互联网地址(如同电话的号码)2. IPv4地址组成三、IP地址分类1. 常用的IP地址2. 组播及科研专用四、IP地址分类(续&#xff0…

wsl下安装cuda各种踩坑记录.assets

执行nvcc -V, cuda版本位11.5 删除cuda sudo apt-get --purge remove "*cublas*" "*cufft*" "*curand*" \"*cusolver*" "*cusparse*" "*npp*" "*nvjpeg*" "cuda*" "nsight*"选择对…

打造自己特色远程桌面:SmartCode ViewerX Crack

SmartCode ViewerX VNC 查看器 ActiveX 毫不费力地将 VNC 查看器功能添加到您的应用程序 SmartCode ViewerX VNC 查看器 ActiveX 使开发人员可以使用一组直观的 ActiveX 属性和方法完全访问 VNC 查看器功能。借助ViewerX 控件,开发人员可以轻松地为其应用程序提供…

<呕心沥血>一文总结数据结构八大排序(持续更新)

目录 一、常见的八大排序 二、八大排序的算法思想 1、冒泡排序 2、选择排序 3、插入排序 4、希尔排序 5、归并排序 6、快速排序 7、堆排序 8、计数排序 三、八大排序的算法实现 一、常见的八大排序 常见的八大排序算法如下: 冒泡排序(Bubble …

Android中的接口回调机制

文章目录1.回调的含义和用途2.java实现接口回调3.Android中接口回调的体现4.接口回调在异步任务中的体现1.回调的含义和用途 一般来说,模块之间都存在一定的调用关系,从调用方式上看,可以分为三类同步调用、异步调用和回调。同步调用是一种阻…

JAVAWeb04-DOM

1. DOM 1.1 概述 1.1.1 官方文档 地址: https://www.w3school.com.cn/js/js_htmldom.asp 1.1.2 DOM 介绍 DOM 全称是 Document Object Model 文档对象模型就是把文档中的标签,属性,文本,转换成为对象来管理 1.2 HTML DOM(文档…

为什么现代企业都在使用ERP系统 它有哪些优势

随着科技的不断发展,企业管理方式也在不断地发生改变。在这个信息化的时代,企业要想取得成功,必须要善于利用先进的信息化技术工具。其中,ERP系统是企业管理中不可或缺的重要工具。本文将探讨现代企业为什么会使用ERP系统&#xf…