前言:
因为平时挺少用到多线程的,写游戏时都在用协程,至于协程那是另一个话题了,除了第一次学习多线程时和以前某个小项目有过就挺少有接触了,最近准备面试又怕被问的深入,所以就赶紧补补多线程基础。
网上已经有很多线程编程的学习笔记了,那我为什么还要再整理一篇呢。因为我在搜索网上文章的时候发现一般别人整理的面试文章那很多语法都一笔带过了默认大家都懂,学习文章又很少有给出经典的题目,一般都是要几篇集合着一起看,既然如此的话我为什么不自己整理出一份呢?自己看的轻松,说不定以后也有人喜欢这种风格能帮助到别人。所以这篇文章也会参考很多其他的文章,最后都会写上引用的。
我写算法的时候也是很喜欢用C++ 来学习,而且笔试的时候我或者很多公司也喜欢用C++,毕竟C++ 的控制台程序输入输出格式化做的也比较好,那为什么这篇又用的是C#而不是C++ 呢?因为最近实习只带着笔记本,我的笔记本上只装了vscode用来写轻量级程序学习。C++装的是MinGW来编译,但是MinGW因为跨平台吧对std::thread支持的又不太好,反正又不是不会用别的语言,最重要的是学习的思想嘛。


一、进程和线程有什么区别?为什么要使用多线程?

首先用最经典的一道面试题作为引入。
①进程是资源分配的最小单位,线程是CPU调度的最小单位。
②一个线程只能属于一个进程,而一个进程可以有多个线程。
③进程在执行过程中拥有独立的内存单元,而多个线程共享进程的内存。
④进程间不会相互影响 ;线程一个线程挂掉将导致整个进程挂掉。
⑤进程编程调试简单可靠性高,但是创建销毁开销大;线程正相反,开销小,切换速度快,但是编程调试相对复杂。
⑥部分任务可能比较耗时,长时间占用CPU(你肯定不希望应用执行某个功能时整个程序都卡死),如果创建进程解决可能额外CPU开销更大,因此部分时候需要使用多线程技术。

二、C# 中使用多线程

在 C# 中,System.Threading.Thread 类用于线程的工作。它允许创建并访问多线程应用程序中的单个线程。进程中第一个被执行的线程称为主线程。 当 C# 程序开始执行时,主线程自动创建使用 Thread 类创建的线程被主线程的子线程调用。
再介绍Thread类中比较有用的一个静态方法,Sleep,用于挂起(可以看成暂停)线程一段时间,参数是毫秒。
下面来一个简单的例子看Thread的使用:

using 

执行该程序首先暂停1秒(1000毫秒),接着连续输出 我是不带参数的线程我是带参数的线程
然后再暂停1秒,接着输出我是不带参数的线程
一开始是在主线程中挂起(暂停)的,所以两个线程都要等1秒才执行,后面是在不带参数的线程中挂起的,不影响另一个线程,所以带参数的线程就直接输出了。
但是要注意的是我这里是在Thread直接指定了方法,但实际上该方法有委托类型

public 

所以说刚刚的实例化可以展开成如下形式

Thread 

这里的参数用的是object,有可能会被问到一个问题就是拆箱装箱,当然拆箱装箱和之前提的委托,包括什么匿名函数、lambda之类的都是另一个话题了,这里为了保持知识的独立性不过多的引入其他特性了,只在必要的时候讲。

三、资源抢占与信号

上面的内容十分简单,似乎跟普通的实例化类调用下函数没什么区别啊。
那我们再用一道面试题作为引入:

两个线程交替打印0~100的奇偶

如果只用上面的知识写出下面的代码,那运行一下就可以发现问题所在了。

using 

结果:

当然这个结果不一定是一样的,毕竟是两个线程并发在跑,但是却只有一个控制台啊,当然,往深一点说就是多个线程共享的资源。
就像十字路口如果不控制车辆开动的顺序,仍由他们乱开会引发严重的后果一样,实际上我们在编程中也经常会遇到控制线程顺序的需求。

那说到这其实也很好理解了,就跟十字路口需要红绿灯一样,我们也会用到信号灯的思想去控制线程的执行顺序。
在C#中有封装好类EventWaitHandle(并不严谨,下期说,这期是为了方便理解概念),有几个成员方法,
WaitOne():如果是红灯的话会将线程暂停在当前位置。
Set():相当于开绿灯,允许被暂停的线程通过开始执行下面的代码了
Reset():相当于开红灯,线程遇到wait会暂停住。

EventWaitHandle必须指定一个枚举类型,AutoReset或ManualReset,ManualReset很好理解,就是手动开关红绿灯。而AutoReset是指在执行Set()后会马上自定执行一次Reset(),相当于只是把当前在红灯前的线程放行。
那么有了这些知识我们就可以开始写代码了

using 

当然,这里写成开了两个flag完全是为了方便理解,事实上可以只开一个叫flag,然后把evenFlag和oddFlag都改成flag,毕竟只有两个线程,要么停要么走嘛。
最后我们似乎能把两个函数再合成成为一个函数,但是这样的话单单一个信号灯似乎是没办法解决的了,可以像上面用两个信号量或者下篇还有机会出来的话讲讲锁。


引用:

.NET面试题解析(07)-多线程编程与线程同步-/梦里花落知多少/

Thread Class-MSDN

C#多线程-菜鸟教程

EventWaitHandle Class-MSDN

多线程C#面试题-Ax0ne

c# 多线程 执行事件 并发_C#.NET Thread多线程并发编程学习与常见面试题解析-1、Thread使用与控制基础...相关推荐

  1. C#.NET Thread多线程并发编程学习与常见面试题解析-1、Thread使用与控制基础

    前言: 因为平时挺少用到多线程的,写游戏时都在用协程,至于协程那是另一个话题了,除了第一次学习多线程时和以前某个小项目有过就挺少有接触了,最近准备面试又怕被问的深入,所以就赶紧补补多线程基础. 网上已 ...

  2. c# 多线程 执行事件 并发_.NET异步和多线程系列(一)

    本系列将和大家分享.Net中的异步多线程,本文是该系列的开篇.首先来看些概念: 进程:计算机概念,虚拟的概念,程序在服务器运行时占据全部计算资源的总和,我们给它起个名字叫进程. 线程:计算机概念,虚拟 ...

  3. android 开启子线程执行for循环_C++11之多线程 - Part2 Joining和Detaching的使用

    std::thread::join()的使用 线程启动后,若想等待该线程结束,可以调用join()方法: std::thread thisThread(function_ptr); // 做一些其他的 ...

  4. 64位浮点数_C语言常见面试题解析(1)——浮点数的比较

    在一些C/C++语言的基础知识考查中,经常会遇到类似这样一个问题,给定两个浮点数,如何来判断它们是否相等? 今天就跟大家探讨一下这个问题,并通过程序试验结果来分析该问题的正确处理方法. 我们知道,在C ...

  5. 「Python-StandardLib」第十六章:并发执行( Cocurrent Executing,线程、多线程队列、子进程)

    参考链接: python多线程 python线程--基于线程的并行 16.1 线程(threading) ps: python ver. is 2.7.18 线程是一项将非连续依赖任务进行分解的技术. ...

  6. 推测的删除锁(Speculative Lock Elision):实现高并发多线程执行

    背景 SLE全称Speculative Lock Elision,我称之为推测的删除锁.这是一篇关于SLE的论文翻译,但是因为本人英语功底很差,所以翻译的不通顺而且会有很多错误的地方.之所以把它发出来 ...

  7. c++并发编程基础(一):并发、并行域多线程

    正文 C++11标准在标准库中为多线程提供了组件,这意味着使用C++编写与平台无关的多线程程序成为可能,而C++程序的可移植性也得到了有力的保证.另外,并发编程可提高应用的性能,这对对性能锱铢必较的C ...

  8. Java并发相关知识(多线程、锁、容器、工具)

    目录 一.基础知识 线程之间如何通信? Java内存模型 内存屏障 顺序一致性 CAS实现原理 原子操作 volatile synchronized 实现原理 什么是锁 原子操作类说明 高性能原子类 ...

  9. 【Java书笔记】:《深入理解Java虚拟机:JVM高级特性与最佳实践(第3版)》第2部分-自动内存管理,第3部分-虚拟机执行子系统,第5部分-高效并发

    作者:周志明 整理者GitHub:https://github.com/starjuly/UnderstandingTheJVM 第2部分-自动内存管理 第2章 Java内存区域与内存溢出异常 2.2 ...

最新文章

  1. android:sharedUserId作用
  2. LeetCode Unique Paths
  3. ms查约束具体代码_记 Arthas 实现一次 CPU 排查与代码热更新
  4. mockjs中的方法(三)
  5. Gensee Android SDK(一)组成结构
  6. Solidity 0.5 address payable和address的区别是什么?
  7. 微软随.NET 4.5发布新REST API框架
  8. python爬取王者_python 爬取王者荣耀高清壁纸
  9. matlab 矢量化编程(三) —— 软阈值函数
  10. 关于MJ刷新的报Too many arguments to function call, expected 0, have *问题
  11. Java 实现 1024 小游戏【附源码】
  12. ORCAD生成BOM单时不显示元器件封装
  13. 信息学奥赛一本通1374 铲雪车(snow)
  14. 读后感:《走出软件作坊》51:幽幽一缕香
  15. python使用venv环境报Python.h : No such file or direc
  16. Python实现Excel表格图片下载-腾讯文档收集表下载Excel表格后下载图片
  17. JVM8(4)java虚拟机内部结构
  18. web服务器双机热备方案解析
  19. 2021年江苏一级计算机报名时间,江苏2021年3月计算机一级报名时间安排
  20. Mac上修改host

热门文章

  1. 使用Angular HTTP client对数据模型进行update操作
  2. Spring JDBC 框架,我的学习笔记
  3. SAP Analytics Cloud导入数据的规模限制
  4. SAP CRM Product category的决定逻辑
  5. SAP FSM 学习笔记(三) 在微信里发起SAP FSM客户预约
  6. How is SAP Gateway metadata request converted to XML format transformation
  7. why SAP OData default 100 entries are returned
  8. ABAP Netweaver上调用Java程序
  9. ABAP SOAMANAGER暴露的函数function module,以web service方式执行的运行时细节
  10. Use BAdI - call_workitem_exit workflow