Unity基础之C#进阶篇笔记7:多线程
- 多线程
- 1.了解线程前先了解进程
- 2.什么是线程
- 3.什么是多线程
- 4.语法相关
- 5.线程之间共享数据
- 6.多线程对于我们的意义
- 7.总结
- 8.练习题
多线程
1.了解线程前先了解进程
进程(Process)是计算机中的程序关于某数据集合上的一次运行活动
是系统进行资源分配和调度的基本单位,是操作系统结构的基础
说人话:打开一个应用程序就是在操作系统上开启了一个进程
进程之间可以相互独立运行,互不干扰
进程之间也可以相互访问、操作
2.什么是线程
操作系统能够进行运算调度的最小单位。
它被包含在进程之中,是进程中的实际运作单位
一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程
我们目前写的程序 都在主线程中
简单理解线程:
就是代码从上到下运行的一条“管道”
3.什么是多线程
我们可以通过代码 开启新的线程
可以同时运行代码的多条“管道” 就叫多线程
4.语法相关
//线程类 Thread
//需要引用命名空间 using System.Threading;
//1.申明一个新的线程
// 注意 线程执行的代码 需要封装到一个函数中
// 新线程 将要执行的代码逻辑 被封装到了一个函数语句块中
Thread t = new Thread(NewThreadLogic);
//2.启动线程
t.Start();
//3.设置为后台线程
//当前台线程都结束了的时候,整个程序也就结束了,即使还有后台线程正在运行
//后台线程不会防止应用程序的进程被终止掉
//如果不设置为后台线程 可能导致进程无法正常关闭
t.IsBackground = true;
//4.关闭释放一个线程
//如果开启的线程中不是死循环 是能够结束的逻辑 那么 不用刻意的去关闭它
//如果是死循环 想要中止这个线程 有两种方式
//4.1-死循环中bool标识
//Console.ReadKey();
//isRuning = false;
//Console.ReadKey();
//4.2-通过线程提供的方法(注意在.Net core版本中无法中止 会报错)
//中止线程
//try
//{
// t.Abort();
// t = null;
//}
//catch
//{
//}
//5.线程休眠
//让线程休眠多少毫秒 1s = 1000毫秒
//在哪个线程里执行 就休眠哪个线程
//Thread.Sleep(1000);
5.线程之间共享数据
多个线程使用的内存是共享的,都属于该应用程序(进程)
所以要注意 当多线程 同时操作同一片内存区域时可能会出问题
可以通过加锁的形式避免问题
lock
当我们在多个线程当中想要访问同样的东西 进行逻辑处理时
为了避免不必要的逻辑顺序执行的差错
lock (引用类型对象)
static void Main(string[] args)
{
while (true)
{
lock(obj)
{
Console.SetCursorPosition(0, 0);
Console.ForegroundColor = ConsoleColor.Red;
Console.Write("●");
}
}
}
static void NewThreadLogic()
{
//新开线程 执行的代码逻辑 在该函数语句块中
while(isRuning)
{
//Thread.Sleep(1000);
//Console.WriteLine("新开线程代码逻辑");
lock(obj)
{
Console.SetCursorPosition(10, 5);
Console.ForegroundColor = ConsoleColor.Yellow;
Console.Write("■");
}
}
}
6.多线程对于我们的意义
可以用多线程专门处理一些复杂耗时的逻辑
比如 寻路、网络通信等等
7.总结
多线程是多个可以同时执行代码逻辑的“管道”
可以通过代码开启多线程,用多线程处理一些复杂的可能影响主线程流畅度的逻辑
关键字 Thread
8.练习题
//控制台中有一个■
//它会如贪食蛇一样自动移动
//请开启一个多线程来检测输入,控制它的转向
enum E_MoveDir
{
Up,
Down,
Right,
Left,
}
class Icon
{
//当前移动的方向
public E_MoveDir dir;
//当前位置
public int x;
public int y;
public Icon(int x, int y, E_MoveDir dir)
{
this.x = x;
this.y = y;
this.dir = dir;
}
//移动
public void Move()
{
switch (dir)
{
case E_MoveDir.Up:
y -= 1;
break;
case E_MoveDir.Down:
y += 1;
break;
case E_MoveDir.Right:
x += 2;
break;
case E_MoveDir.Left:
x -= 2;
break;
}
}
//绘制
public void Draw()
{
Console.SetCursorPosition(x, y);
Console.Write("■");
}
//擦除
public void Clear()
{
Console.SetCursorPosition(x, y);
Console.Write(" ");
}
//转向
public void ChangeDir(E_MoveDir dir)
{
this.dir = dir;
}
}
class Program
{
static Icon icon;
static void Main(string[] args)
{
Console.WriteLine("多线程练习题");
#region 练习题
Console.CursorVisible = false;
icon = new Icon(10, 5, E_MoveDir.Right);
icon.Draw();
//开启多线程
Thread t = new Thread(NewThreadLogic);
t.IsBackground = true;
t.Start();
while (true)
{
Thread.Sleep(500);
icon.Clear();
icon.Move();
icon.Draw();
}
#endregion
}
static void NewThreadLogic()
{
while (true)
{
switch(Console.ReadKey(true).Key)
{
case ConsoleKey.W:
icon.ChangeDir(E_MoveDir.Up);
break;
case ConsoleKey.A:
icon.ChangeDir(E_MoveDir.Left);
break;
case ConsoleKey.S:
icon.ChangeDir(E_MoveDir.Down);
break;
case ConsoleKey.D:
icon.ChangeDir(E_MoveDir.Right);
break;
}
}
}
}