天天看點

unity c# 子線程與主線程資料傳遞

    引言:在Unity裡做AI大量模型運算處理,如果在update裡進行處理會阻塞主線程,導緻掉幀,這個時候需要單獨開辟一個線程進行資料處理,緩解主線程處理壓力。

應用了網友的一個處理方法,測試可用,整理一下,備忘。

using System.Threading;

//消息結構  
public class Message
{
   public ActionType type;//枚舉類型
   public int p_number;//檢測到的人數
   public byte[] byte_frame;
}

List<Message> messageList = new List<Message>();

//使用該方法在Unity的update裡往外取資料
private void Dispatch()
{
    lock (((ICollection)messageList).SyncRoot)
    {
        if (messageList.Count > 1)
        {
            HandleMessage(messageList[1]);
            messageList.RemoveAt(0);
        }
        else//補幀
        {
           HandleMessage(messageList[0]);
         }
    }
}

//消息格式
 private void HandleMessage(Message message)
 {
     switch (message.type)
     {
         case ActionType.CV_8UC1:
             break;
         case ActionType.CV_8UC2:
             break;
         case ActionType.CV_8UC3:
             break;
         case ActionType.CV_8UC4:
             Texture2UI(message.byte_frame, message.p_number);
             break;
     }
 }

//開啟線程
private void StartNewThread()
{
  Thread thread = new Thread(new ThreadStart(SubThread));
  thread .Start();
  Debug.Log("begin_thread.....");
}

//開啟線程後這裡會壓資料
private void SubThread()
{
   while (mask_switch)//采集開關
   {
      if (messageList.Count < 200)//設定緩沖大小
      {
          int num_obj = xlsYolect.xls_get_num_boject();
          byte[] temp_byte = xlsYolect.xls_get_byte_frame();
          messageList.Add(new Message() { type = ActionType.CV_8UC4, p_number = num_obj, byte_frame = temp_byte });
      }
   }
}

           

總結:思路就是在Unity的腳本 Start() 裡開啟一個線程,線程中進行while 循環,用于處理計算量比較大的AI模型,處理完的結果壓入自己開辟的緩沖區 List<Message>,然後在Update()裡取出處理結果。