• unity3D中协程和线程混合


    这是我google unity3D一个问题偶然发现的在stackflow上非常有趣的帖子:

    大意是 要在unity3D上从server下载一个zip,并解压到持久化地址.并将其载入到内存中.以下展示了这样的使用方法:

    IEnumerator LongCoroutine()
    {
        yield return StartCoroutine(DownloadZip());
        ExtractZip();
        yield return StartCoroutine(LoadZipContent());
    }

    可是ExtractZip()方法是同步的,这将挂起进程.结果是不管怎样试图解压zip,进程将会被杀死.我觉得是主线程太久没有响应,所以被os杀死.

    所以我猜想将提取zip放在单独线程可能会解决这个问题,并且看起来这样奏效了.我写了这样一个类:

    public class ThreadedAction
    {
        public ThreadedAction(Action action)
        {
            var thread = new Thread(() => {
                if(action != null)
                    action();
                _isDone = true;
            });
            thread.Start();
        }
    
        public IEnumerator WaitForComplete()
        {
            while (!_isDone)
                yield return null;
        }
    
        private bool _isDone = false;
    }

    如此用它:

    IEnumerator LongCoroutine()
    {
        yield return StartCoroutine(DownloadZip());
        var extractAction = new ThreadedAction(ExtractZip);
        yield return StartCoroutine(extractAction.WaitForComplete());
        yield return StartCoroutine(LoadZipContent());
    }

    可是我仍旧不确定这是不是最好的解决的方法.我是否须要锁定_isDone(not too used to multithreading).

    楼主已经给出解决方法了,原来在球完美之道,哈哈.

    以下的跟帖是:

    这真是在协程里糅合多线程的优雅方案.做得好!

    Mixing coroutines and threads is perfectly safe, provided you correctly lock access to resources shared between your main thread (which the coroutine executes on) and the worker thread(s) you create. You shouldn't need to lock _isDone in any way, since it's only ever written to by the worker thread and there's no intermediate state that could cause the main thread to misbehave.

    混合协程和线程是全然线程安全的,它为了正确锁定主线程(协程所在的)和工作线程(可能多个)的共享资源.你不须要锁定_isDone.由于它仅仅会在工作线程中写,没有交替状态会引起主线程误解.

    你须要注意的潜在问题是,假设不论什么资源被ExtractZip写入,而且 

    1.同一时候在主线程里的一个函数写入

    2.或者在主线程被读取,仅仅有在ExtracrZip完毕后才是线程安全的.

    In this particular case, my worry would be that if you don't check that you're not trying to download the same file to the same location twice, you could have two threads simultaneously running ExtractZip that interfere with one another.

    特别情况是,我操心假设你不去检測你不会试图下载同一个文件到同一个位置两次,你能够有两个线程并行执行在ExtractZip.


  • 相关阅读:
    shell去重
    JDBC源码解析
    try catch finally
    URL
    域名与IP地址的联系与区别
    C++stack
    C++vector
    单链表常见面试题(C语言实现)
    数据库limit子句
    strcpy和memcpy的区别
  • 原文地址:https://www.cnblogs.com/bhlsheji/p/4030254.html
Copyright © 2020-2023  润新知