• 同步异步和阻塞5-异步非阻塞


    项目简介和code见《同步异步和阻塞2-测试小项目

    1. 实现

    1> 异步线程IO处理

    unsigned CAsyncIO::ThreadWork()
    {
    
        int nRet = IO();
    
        //map is better than array at here, but it need STL
        unsigned uTid = GetCurrentThreadId();
        for (int i = 0; i < sizeof(m_uThreadArray) / sizeof(m_uThreadArray[0]); i++)
        {
            //Because handle is not same at different thread, so it need use tid to associate the thread and IO caller.
            if (uTid == m_uThreadArray[i])
            {
                NotifyProgress(100, i);
                NotifyResult(nRet, i);
            }
        }
    
        return    nRet;
    }

    线程调用完IO后,直接通知UI结果。

    2> OnStart()

    bool CAsyncIO::OnStart()
    {
        OnStop();
        for (int i = 0; i < sizeof(m_uThreadArray) / sizeof(m_uThreadArray[0]); i++)
        {
            HANDLE hThread = StartThread();
            m_hThreadHandleArray[i] = hThread;
            m_uThreadArray[i] = ::GetThreadId(hThread);
        }
    
        return    true;
    }

    OnStart()只要把线程启动处理IO即可返回,这样就不会再阻塞UI主线程,”Start”按钮在返回后会变为”Stop”。

    3> Stop的实现

    由于IO不再阻塞主线程,所以“Stop”按钮变为可用,Stop的实现就变得有意义。

    bool CAsyncIO::OnStop()
    {
        for (int i = 0; i < sizeof(m_hThreadHandleArray) / sizeof(m_hThreadHandleArray[0]); i++)
        {
            HANDLE hThread = m_hThreadHandleArray[i];
            if (hThread)
            {
                TerminateThreadUntilExit(hThread);
                ::CloseHandle(hThread);
                m_hThreadHandleArray[i] = NULL;
            }
        }
    
        return    true;
    }

    这里Stop()的实现仅仅是简单的Terminate掉线程,由于直接终止线程,无法知道线程所处的状态,会出现什么情况无法预知,有时会出现莫名奇妙的问题,微软也是不推荐的,需谨慎使用。

    2. 测试

    点击”Start”按钮后,虽然IO没有处理完毕,但是按钮立即变为可用的”Stop”,同时UI窗口也是可以随意移动操作的。

    image

    异步非阻塞模式不阻塞UI主线程,用户体验上是最好的。同时在并发处理上也相对同步非阻塞模式简单,当然由于需要在IO处理完毕后通过callback通知UI主线程,这必然会涉及到线程同步的问题,线程同步是个非常头疼的问题,在异步模式带来的好处不是远远大于同步模式的情况下,其带来的问题会远远大于同步模式。

  • 相关阅读:
    Java EE (3) -- Java EE 6 Web Services Developer Certified Expert(1z0-897)
    二、用电信号传输 TCP/IP 数据(1)
    P2384 最短路 洛谷
    T1231 最优布线 codevs
    P3371 单源最短路径【模板】 洛谷
    spfa【模板】
    P1396 营救 洛谷
    解决Android加固多进程ptrace反调试的思路整理
    Android Dex文件格式解析
    360加固保so动态脱壳
  • 原文地址:https://www.cnblogs.com/organic/p/7784113.html
Copyright © 2020-2023  润新知