简体   繁体   English

ConditionVariable防止两个线程同时运行

[英]ConditionVariable prevents both threads from running simultaneously

I am trying to enforce synchronization between a pair of Android threads for game programming purposes. 我正在尝试出于游戏编程目的在一对Android线程之间强制执行同步。 I have assigned a game thread, which handles most duties, and a render thread, which is tasked with swapping buffers and rendering. 我分配了一个游戏线程来处理大多数任务,并分配了一个渲染线程,负责交换缓冲区和渲染。 When I first asked about thread synchronization, I was referred to the ConditionVariable object as a useful tool to force threads to block until concurrent tasks are completed. 当我第一次询问线程同步时,我将ConditionVariable对象称为一种有用的工具,可以强制线程阻塞直到并发任务完成。

My source code looks like this: 我的源代码如下所示:

            ...
            final ConditionVariable bufferLock = new ConditionVariable();
            final ConditionVariable cycleLock = new ConditionVariable();

            bufferLock.open();
            cycleLock.open();

            Runnable bufferSwapTask = new Runnable()
            {
                public void run()
                {
                    swapBuffers();
                    bufferLock.open();
                }
            };

            Runnable renderTask = new Runnable()
            {
                public void run()
                {
                    Log.d(TAG, "drawAll");
                    drawAll();
                    cycleLock.open();
                }
            };

            while(!halt)
            {
                if(!init)
                {
                    synchronized (userInputLock)
                    {
                        fetchUserInput();
                    }

                    processUserInput();
                    gameLogic();

                    bufferLock.block();
                    cycleLock.close();
                    renderThreadHandler.post(renderTask);
                    recycleDisplayObjects();
                    enqueueDisplayTree();

                    cycleLock.block();
                    bufferLock.close();
                    renderThreadHandler.post(bufferSwapTask);
                }
            }
            ...

So things executed in the right order, but not with the level of performance I had expected. 因此,事情以正确的顺序执行,但没有达到我期望的性能水平。 And, when I activated DDMS method tracing, I found that the DVM would actually interrupt and block each thread to allow the other thread to resume, switching back and forth in a manner that strongly suggests that both threads are only being processed by one CPU. 而且,当我激活DDMS方法跟踪时,我发现DVM实际上会中断并阻塞每个线程以允许另一个线程继续进行,来回切换的方式强烈暗示两个线程仅由一个CPU处理。

I have had nice simultaneous processing results using ReentrantLocks, so why does ConditionVariable have this effect? 使用ReentrantLocks的同时处理效果很好,为什么ConditionVariable会产生这种效果?

The Linux kernel on Android tries to avoid moving threads between cores. Android上的Linux内核试图避免在内核之间移动线程。 If a thread is "runnable" (ie could run but is waiting on another thread) for a while, the kernel can decide to migrate it to another core. 如果某个线程“可运行”(即可以运行但正在等待另一个线程)一段时间,则内核可以决定将其迁移到另一个内核。

If, in the previous implementation, one of your threads tended to run continuously, it may have kept the other thread in "runnable" long enough to cause the kernel to migrate it. 如果在以前的实现中,您的一个线程趋向于连续运行,则它可能已将另一个线程保持在“可运行”状态的时间足够长,足以导致内核对其进行迁移。 The new implementation might be moving in smaller steps and fall below the threshold. 新的实现可能会以较小的步伐移动并低于阈值。

FWIW, other people have been puzzled by this, eg here and here . FWIW,其他人对此感到困惑,例如在这里这里

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM