Unity 线程相关知识

devtools/2024/10/21 3:15:17/

线程

线程介绍

通过线程执行函数和直接在主函数中调用函数的区别是:通过直接调用函数时会按照语句顺序逐句执行,必定会完成上一句后再执行下一句,而通过线程执行的函数会从调用开始与主函数同步执行

调用线程的方式

调用无参数函数线程的方法:

    void Start(){Thread thread = new Thread(SendThread);thread.Start();}void SendThread(){Debug.Log("调用线程");}

调用有参数函数线程时,使用lambda表达式在创建线程时传入函数的参数

    void Start(){Thread t1 = new Thread(() => { SendThread("一", 100); });Thread t2 = new Thread(() => { SendThread("二", 50); });Thread t3 = new Thread(() => { SendThread("三", 25); });t1.Start();t2.Start();t3.Start();}void SendThread(string name,int i){while (i >= 0){Debug.Log(name + "执行剩余" + i--);}}

线程休眠 

调用Thread.Sleep(int)方法

public static void Sleep(int millisecondsTimeout);

传入的参数为毫秒,1000毫秒等于一秒

            //线程休眠一秒Thread.Sleep(1000);

线程池

线程池介绍

在调用线程的时候,会先创建线程,然后再线程结束后销毁线程,如果频繁对线程进行创建和销毁会极大的损耗计算机的性能,所以在频繁创建逻辑简短的线程的时候,最好使用线程池

调用线程池的方法

能够在线程池中调用的线程与直接创建线程不同的地方在于:线程池中调用的线程的参数必须限定格式,线程池能调用的线程必须只能拥有一个object类型的参数

通过ThreadPool.QueueUserWorkItem方法使用线程池调用线程

public static bool QueueUserWorkItem(WaitCallback callBack, object state);

第一个参数为想要执行线程的函数,函数必须只有一个object参数

第二个参数为传递给线程函数的参数

与直接创建线程不同的是,线程池中的线程不需要Start,添加线程时自动开始执行

示例代码:

    void Start(){ThreadPool.QueueUserWorkItem(SendThreadPool,10);ThreadPool.QueueUserWorkItem(SendThreadPool,10.01);ThreadPool.QueueUserWorkItem(SendThreadPool,"十");}void SendThreadPool(object obj){for (int i = 0; i < 10; i++){Debug.Log(obj.ToString() + "剩余" + i);}}

设置线程池中最多同时运行线程数量

public static bool SetMaxThreads(int workerThreads, int completionPortThreads);

第一个参数为线程池中辅助线程的最大数目,与第二个参数相同即可

第二个参数为线程池中异步 I/O 线程的最大数目,与第一个参数相同即可

示例代码:

ThreadPool.SetMaxThreads(10,10);

线程同步

线程同步介绍

线程的运行是不规律的,结果不可控的,可能会涉及到一个线程中使用一个值之前这个值被另一个线程改变了,从而导致出现未知错误,这种情况下就需要控制线程执行的顺序,规避问题

Mutex 互斥锁

通过定义Mutex类型变量互斥锁,来达到同步效果,可以在执行重要逻辑前先对Mutex类型变量进行锁定,然后第二个线程尝试执行锁定Mutex变量时如果Mutex变量已被锁定,则第二个线程将会暂停运行,直到第一个锁定Mutex变量的线程将Mutex变量解锁,第二个线程才会继续锁定Mutex变量并开始工作,直到再次解锁Mutex变量为止

示例代码:

    int number;Mutex mutex = new Mutex();void Start(){Thread t1 = new Thread(() => { SendThread("一",10); });Thread t2 = new Thread(() => { SendThread("二",8); });Thread t3 = new Thread(() => { SendThread("三",5); });t1.Start();t2.Start();t3.Start();}void SendThread(string name,int i){for (; i > 0; i--){mutex.WaitOne();for (int j = 0; j < i; j++){number += i;Debug.Log(name + "给数值增加了" + i + "现在的数值为" + number);}mutex.ReleaseMutex();}}

Lock 变量锁

通过Lock关键字来达到同步效果,和Mutex使用相似,执行重要逻辑前,锁住任意变量,将逻辑写入lock语句内,其余线程执行lock发现lock中的变量被锁住将会等待,等待前一线程的lock执行完毕释放lock关键字中的变量后再执行(lock锁住的变量可以和需要保护的变量毫无关系,可以锁住任意变量达到效果,但注意变量类型必须是引用类型,值类型变量无法使用lock关键字)

示例代码:

    int number;object obj = new object();void Start(){Thread t1 = new Thread(() => { SendThread("一",10); });Thread t2 = new Thread(() => { SendThread("二",8); });Thread t3 = new Thread(() => { SendThread("三",5); });t1.Start();t2.Start();t3.Start();}void SendThread(string name,int i){for (; i > 0; i--){lock (obj) {for (int j = 0; j < i; j++){number += i;Debug.Log(name + "给数值增加了" + i + "现在的数值为" + number);}}Thread.Sleep(100);}}

Semaphore 多通道锁

Semaphore与Mutex不同的地方在于,Mutex一次只能固定允许一个线程访问,而Semaphore可以设置最多同时访问的最大数量,如果给Semaphore的最大访问值设置为2,同时有10个线程需要访问时,只有前2个线程能够成功访问,而剩余的8个线程则需要等待,等前两个线程执行完后,再同时让第3和第4个访问通道的线程执行,剩余的6个线程等待,直到执行完毕

示例代码:

    int number;Semaphore semaphore = new Semaphore(2,2);void Start(){Thread t1 = new Thread(() => { SendThread("一", 10); });Thread t2 = new Thread(() => { SendThread("二", 8); });Thread t3 = new Thread(() => { SendThread("三", 5); });t1.Start();t2.Start();t3.Start();}void SendThread(string name, int i){for (; i > 0; i--){semaphore.WaitOne();for (int j = 0; j < i; j++){number += i;Debug.Log(name + "给数值增加了" + i + "现在的数值为" + number);}semaphore.Release();}}

http://www.ppmy.cn/devtools/10251.html

相关文章

密码学系列0-总述

通过这一系列文章&#xff0c;帮助读者能快速入门密码学安全性证明。 这一系列文章主要包括以下内容&#xff1a; 1.可证明安全的概念 2.密码学常用困难性问题&#xff1a;CDH,DDH,DLP,BDH等。然后讨论问非对称&#xff0c;对称双线性配对上困难性问题。讨论为什么对称双线性DD…

vue整合Echarts

首先打开网址https://echarts.apache.org/examples/zh/index.html 进入Echars官网找到自己想要的图形我这里选择的是柱形图 点开完整代码直接cv大法 下载Echars的npm npm install echarts 在vue里面挂在个div 导入相关包 写个方法 就是cv过来的 然后改成后端传过来的值…

C语言程序环境和预处理

系列文章目录 第一章 C语言基础知识 第二章 C语言控制语句 第三章 C语言函数详解 第四章 C语言数组详解 第五章 C语言操作符详解 第六章 C语言指针详解 第七章 C语言结构体详解 第八章 详解数据在内存中的存储 第九章 C语言指针进阶 第十章 C语言字符函数和字符串函数…

Redis入门到通关之Redis数据结构-String篇

文章目录 欢迎来到 请回答1024 的博客 &#x1f353;&#x1f353;&#x1f353;欢迎来到 请回答1024的博客 关于博主&#xff1a; 我是 请回答1024&#xff0c;一个追求数学与计算的边界、时间与空间的平衡&#xff0c;0与1的延伸的后端开发者。 博客特色&#xff1a; 在我的…

大语言模型(LLM)漏洞爆发,AI模型无一幸免

本文概述了人工智能初创公司Anthropic于2024年04月03日发表的一篇针对人工智能安全的论文&#xff0c;该公司在本论文中宣布的一种新的“越狱”技术&#xff0c;名为Many-shot Jailbreaking&#xff08;多轮越狱&#xff09;。文章详细描述了目前大语言模型&#xff08;LLM&…

举例详解 TCP/IP 五层(或四层)模型与 OSI七层模型对比 (画图详解 一篇看懂!)

目录 一、为什么要对协议进行分层 1、什么是协议分层 2、协议分层的好处 二、TCP/IP 五层&#xff08;或四层&#xff09;模型 1、概念 应用层 传输层 网络层 数据链路层 物理层 2、举例详解 传输层 网络层 数据链路层 和 物理层 应用层 四、TCP/IP 五层&…

牛客NC238 加起来和为目标值的组合【中等 DFS C++、Java、Go、PHP】

题目 题目链接&#xff1a; https://www.nowcoder.com/practice/172e6420abf84c11840ed6b36a48f8cd 思路 本题是组合问题&#xff0c;相同元素不同排列仍然看作一个结果。 穷经所有的可能子集&#xff0c;若和等于target&#xff0c;加入最终结果集合。 给nums排序是为了方便…

OSPF的防止环路的机制

OSPF协议中避免环路的机制包括以下几点&#xff1a; 1.区域内防环&#xff1a;在同一OSPF区域内&#xff0c;所有路由器通过交换链路状态通告&#xff08;LSA&#xff09;来共享网络拓扑信息。每台路由器根据这些信息使用最短路径优先&#xff08;SPF&#xff09;算法&#xff…