程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> C#在Unity游戲開發中進行多線程編程的方法

C#在Unity游戲開發中進行多線程編程的方法

編輯:關於C語言

在這之前,有很多人在質疑Unity支不支持多線程,事實上Unity是支持多線程的。而提到多線程就要提到Unity非常常用的協程,然而協程並非真正的多線程。協程其實是等某個操作完成之後再執行後面的代碼,或者說是控制代碼在特定的時機執行。而多線程在Unity渲染和復雜邏輯運算時可以高效的使用多核CPU,幫助程序可以更高效的運行。本篇主要介紹在Unity中如何使用多線程。

首先引入C#中使用多線程的類庫

? 1 using System.Threading;

創建線程實例的四種方式

一、線程執行無參方法

構造語法

? 1 2 3 // 初始化 Thread 類的新實例。 // < param name="start">無參委托對象.</ param> public Thread(ThreadStart start)

start

類型:System.Threading.ThreadStart
表示開始執行此線程時要調用的方法的 ThreadStart 委托。

? 1 2 3 4 5 6 7 8 9 10 11 12 13 void Start() { //創建無參線程對象 Thread thr = new Thread(Func_NoArguments); //啟動線程 thr.Start(); } // Function Of No Arguments. void Func_NoArguments() { Debug.Log("Run Func_NoArguments"); }

二、線程執行有參方法

構造語法

? 1 2 3 // 初始化 Thread 類的新實例。 // < param name="start">有參委托對象.< /param> public Thread(ParameterizedThreadStart start)

start

類型:System.Threading.ParameterizedThreadStart
一個委托,它表示此線程開始執行時要調用的方法。
注意:參數只能有一個,且必須為object類型

實例

? 1 2 3 4 5 6 7 8 9 10 11 12 void Start() { //創建有參線程對象 Thread thr = new Thread(Func_Arguments); //啟動線程,傳入參數 thr.Start("Lanou"); } // Function Of Have Arguments. void Func_Arguments(object data) { Debug.Log("Run Func_Arguments, Data = " + data); }

三、線程執行無參方法,限制線程要使用的最大堆棧大小

構造語法

? 1 2 3 4 // 初始化 Thread 類的新實例。 // < param name="start">無參委托對象.< /param> // < param name="maxStackSize">使用的最大堆棧大小.< /param> public Thread(ThreadStart start,int maxStackSize)

start

類型:System.Threading.ThreadStart
表示開始執行此線程時要調用的方法的 ThreadStart 委托。

maxStackSize

類型:System.Int32
線程要使用的最大堆棧大小(以字節為單位);如果為 0,則使用可執行文件的文件頭中指定的默認最大堆棧大小。
重要事項:對於部分受信任的代碼,如果 maxStackSize 大於默認堆棧大小,則將其忽略。 不引發異常。

? 1 2 3 4 5 6 7 8 9 10 11 12 void Start() { //創建無參線程對象,限制256KB堆棧大小 Thread thr = new Thread(Func_NoArguments,262144); //啟動線程 thr.Start(); } // Function Of No Arguments. void Func_NoArguments() { Debug.Log("Run Func_NoArguments"); }

四、線程執行有參方法,限制線程要使用的最大堆棧大小

構造語法

? 1 2 3 4 // 初始化 Thread 類的新實例。 // < param name="start">有參委托對象.< /param> // < param name="maxStackSize">使用的最大堆棧大小.< /param> public Thread(ParameterizedThreadStart start,int maxStackSize)

start

類型:System.Threading.ParameterizedThreadStart
一個委托,它表示此線程開始執行時要調用的方法。
注意:參數只能有一個,且必須為object類型

maxStackSize

類型:System.Int32
線程要使用的最大堆棧大小(以字節為單位);如果為 0,則使用可執行文件的文件頭中指定的默認最大堆棧大小。
重要事項:對於部分受信任的代碼,如果 maxStackSize 大於默認堆棧大小,則將其忽略。 不引發異常。

實例

? 1 2 3 4 5 6 7 8 9 10 11 12 void Start() { //創建有參線程對象,限制256KB堆棧大小 Thread thr = new Thread(Func_Arguments,262144); //啟動線程,傳入參數 thr.Start("Lanou"); } // Function Of Have Arguments. void Func_Arguments(object data) { Debug.Log("Run Func_Arguments, Data = " + data); }

啟動線程(上文已使用)

無參啟動

? 1 2 3 4 5 6 7 8 9 10 11 12 void Start() { //創建無參線程對象 Thread thr = new Thread(Func_NoArguments); //啟動線程 thr.Start(); } // Function Of No Arguments. void Func_NoArguments() { Debug.Log("Run Func_NoArguments"); }

有參啟動

? 1 2 3 4 5 6 7 8 9 10 11 12 void Start() { //創建有參線程對象 Thread thr = new Thread(Func_Arguments); //啟動線程,傳入參數 thr.Start("Lanou"); } // Function Of Have Arguments. void Func_Arguments(object data) { Debug.Log("Run Func_Arguments, Data = " + data); }


常用方法

1.public static void Sleep( int millisecondsTimeout)將當前線程掛起指定的毫秒數。
(1)millisecondsTimeout
類型:System.Int32
掛起線程的毫秒數。 如果 millisecondsTimeout 參數的值為零,則該線程會將其時間片的剩余部分讓給任何已經准備好運行的、有同等優先級的線程。 如果沒有其他已經准備好運行的、具有同等優先級的線程,則不會掛起當前線程的執行。
(2)public void Resume()
繼續已掛起的線程。(已過時)
(3)public void Abort()
在調用此方法的線程上引發 ThreadAbortException,以開始終止此線程的過程。 調用此方法通常會終止線程。
(4)public void Join()
阻止調用線程直到線程終止,同時繼續執行標准的 COM 和 SendMessage 傳送。
(5)public enum ThreadPriority
指定 Thread 的調度優先級。

2016421152923973.png (1248×630)

通過線程池執行線程

2.ThreadPool.QueueUserWorkItem 方法 (WaitCallback)
public static bool QueueUserWorkItem(WaitCallback callBack)
callBack
類型:System.Threading.WaitCallback
一個 WaitCallback,表示要執行的方法。
返回值
類型:System.Boolean
如果此方法成功排隊,則為 true;如果無法將該工作項排隊,則引發 NotSupportedException。

Unity使用多線程注意

變量都是共享的(都能指向相同的內存地址)
UnityEngine的API不能在分線程運行
UnityEngine定義的基本結構(int,float,Struct定義的數據類型)可以在分線程計算,如 Vector3(Struct)可以 , 但Texture2d(class,根父類為Object)不可以。
UnityEngine定義的基本類型的函數可以在分線程運行
Unity多線程插件

LOOM Multi Threading Framework 1.7

核心方法

? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 // Unlike "StartMultithreadedWorkloadExecution", you will have to build your own IThreadWorkerObject. // Downside: It requires some extra work. Upside: you got more controll over what goes in and comes out // Infact: You can create you own polymorphed IThreadWorkerObject-array, each ellement being a completely different type. For example: the stateMachines of enemies are IThreadWorkerObject's and the array contains completely different classes with enemIEs/AI-behaviours. // < param name="workerObjects">An array of IThreadWorkerObject objects to be handled by the threads. If you want multiple cores/threads to be active, make sure that the number of IThreadWorkerObject's proves matches/exeeds your preferred number maxWorkingThreads. < /param> // < param name="onComplete">Fired when all re-packaged workLoad-objects are finished computing< /param> // < param name="onPackageExecuted">Fires foreach finished re-packaged set of workLoad-object< /param> // < param name="maxThreads"> Lets you choose how many threads will be run simultaneously by the threadpool. Default: -1 == number of cores minus one, to make sure the MainThread has at least one core to run on. (quadcore == 1 core Mainthread, 3 cores used by the ThreadPoolScheduler)< /param> // < param name="scheduler">If Null, a new ThreadPoolScheduler will be instantiated.< /param> // < param name="safeMode">Executes all the computations within try-catch events, logging it the message + stacktrace< /param> // < returns>A ThreadPoolScheduler that handles all the repackaged workLoad-Objects< /returns> public static ThreadPoolScheduler StartMultithreadedWorkerObjects(IThreadWorkerObject[] workerObjects, ThreadPoolSchedulerEvent onCompleteCallBack, ThreadedWorkCompleteEvent onPackageExecuted = null, int maxThreads = -1, ThreadPoolScheduler scheduler = null, bool safeMode = true) { if (scheduler == null) scheduler = CreateThreadPoolScheduler(); scheduler.StartASyncThreads(workerObjects, onCompleteCallBack, onPackageExecuted, maxThreads, safeMode); return scheduler; }


結束語

Unity可以使用多線程,但對其有很多限制,所以在不使用UnityEngine API的情況下,可以使用多線程,提高多核CPU的使用率。通常可以將需要大量計算的算法內容,放置到多線程中執行,包括邏輯框架也可以放到多線程中執行。本篇理論性較強,後期會陸續發布實戰型文章。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved