GVKun编程网logo

Interrupt Handler使用哪个堆栈 – Linux(狸奴小睡不知愁,忙添落花作锦衾)

22

如果您对InterruptHandler使用哪个堆栈–Linux感兴趣,那么本文将是一篇不错的选择,我们将为您详在本文中,您将会了解到关于InterruptHandler使用哪个堆栈–Linux的详细

如果您对Interrupt Handler使用哪个堆栈 – Linux感兴趣,那么本文将是一篇不错的选择,我们将为您详在本文中,您将会了解到关于Interrupt Handler使用哪个堆栈 – Linux的详细内容,我们还将为您解答狸奴小睡不知愁,忙添落花作锦衾的相关问题,并且为您提供关于android中的runOnMainThread vs Handler-何时针对上述场景使用哪个、C3P0:java.lang.InterruptedException: sleep interrupted、Disruptor (5) - 消费方式 EventHandler & WorkHandler、HanderThread 的 quit 和 interrupt的有价值信息。

本文目录一览:

Interrupt Handler使用哪个堆栈 – Linux(狸奴小睡不知愁,忙添落花作锦衾)

Interrupt Handler使用哪个堆栈 – Linux(狸奴小睡不知愁,忙添落花作锦衾)

在多任务系统中,当任何硬件对特定的cpu产生中断时,除非cpu已经在服务ISR,否则cpu可以执行以下任一种情况:

用户模式进程正在cpu上执行

内核模式进程正在cpu上执行

想知道在以上两种情况下哪个堆栈被中断处理程序使用,为什么?

所有的中断都由内核来处理。 这是通过为特定中断编写的中断处理程序完成的。 中断处理程序有IRQ堆栈。 中断处理程序的堆栈的设置是配置选项。 内核堆栈的大小可能并不总是足够内核工作和IRQ处理例程所需的空间。 因此2堆栈进入图片。

硬件IRQ堆栈。

软件IRQ堆栈。

与每个进程分配的常规内核堆栈相反,两个附加堆栈是按cpu分配的。 无论何时发生硬件中断(或者处理软IRQ),内核都需要切换到相应的堆栈。 历史上,中断处理程序没有收到自己的堆栈。 相反,中断处理程序将共享运行进程的堆栈,它们中断。 内核堆栈有两页大小, 通常,在32位体系结构上是8KB,而在64位体系结构上是16KB。 因为在这个设置中,中断处理程序共享堆栈,所以它们必须非常节约地分配在那里的数据。 当然,内核栈仅限于开始,所以所有的内核代码都要谨慎。

中断只能由内核处理。 所以它是使用的一些内核堆栈(在这两种情况下)。

中断不会影响(直接)用户进程 。

进程可能会得到信号 ,但这些不是中断。 见信号(7) …

android中的runOnMainThread vs Handler-何时针对上述场景使用哪个

android中的runOnMainThread vs Handler-何时针对上述场景使用哪个

如何解决android中的runOnMainThread vs Handler-何时针对上述场景使用哪个?

我在活动中的onCreateOptionsMenu方法中实现了一个标记。

/* Coachmark - preview */
        if (preview.isEnabled(uuserID)) {
            new runOnMainThread(() -> {
                    final View anchorView = findViewById(R.id.action_preview);
                    if (anchorView != null) {
                        new CoachMark.Builder(PreviewActivity.this,anchorView,CoachMarkType.CoachMarkDirection.TOP)
                                .setText(R.string.hello_tooltip)
                                .setTextStyleId(R.style.AppStatusBarTextStyle)
                                .seTradius(MiscUtils.dpToPixel(PreviewActivity.this,4))
                                .dismissOnTouch(true)
                                .dismissOnTouchOutside(true)
                                .build()
                                .show();
                    }
            });
        }

public static Task<Void> runOnMainThread(@NonNull Runnable runnable) {
    return runOnExecutor(runnable,Task.UI_THREAD_EXECUTOR,null);
}

当活动成为焦点时,它会加载文件并为该活动创建选项Menu。我从createOptionsMenu调用了标记,并且当我使用runOnMainThread()运行线程时,标记未显示,而使用Handler()。post()时,显示了标记。为什么以及何时使用处理程序以及何时使用runOnMainThread()的任何原因。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

C3P0:java.lang.InterruptedException: sleep interrupted

C3P0:java.lang.InterruptedException: sleep interrupted

好好的就报异常了~~

警告: com.mchange.v2.resourcepool.BasicResourcePool@8fce95 -- Thread unexpectedly interrupted while performing an acquisition attempt.
java.lang.InterruptedException: sleep interrupted
	at java.lang.Thread.sleep(Native Method)
	at com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask.run(BasicResourcePool.java:1805)
	at com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:547)

Disruptor (5) - 消费方式 EventHandler & WorkHandler

Disruptor (5) - 消费方式 EventHandler & WorkHandler

handleEventsWith & handleEventsWithWorkerPool

Disruptor.start方法执行之前,需要指定消息的处理方式。消费者对于同一消息: 都分别独立消费应当实现EventHandler接口;不重复消费则应当实现WorkHandler接口。

有不同的实现逻辑来支持不同的模式:

com.lmax.disruptor.dsl.ConsumerInfo

com.lmax.disruptor.EventProcessor

  1. disruptor.handleEventsWith(EventHandler... handlers):将多个EventHandler的实现类传入,封装成一个com.lmax.disruptor.dsl.EventHandlerGroup<T>。每个消费者都会对同一条消息进行独立消费,各个消费者之间不存在竞争。事件的处理类是BatchEventProcessor + EventProcessorInfo
  2. disruptor.handleEventsWithWorkerPool(WorkHandler... handlers):将多个WorkHandler的实现类传入,封装成一个EventHandlerGroup<T>。对于同一条消息不重复消费;如果c0消费了消息m,则c1不再消费消息m。事件信息的处理类是com.lmax.disruptor.WorkerPool(N个WorkProcessor)+ WorkerPoolInfo

Demo

public class CompareTest {
	public static int THREAD = 2; // 线程数量
	public static int PER = 1; // 单个线程生产数量
	public static int TOTAL_COUNT = THREAD * PER; // 数据总量
	public static int SIZE = 4; // 最大容量

	public static void main(String[] args) {
		println("线程数:" + THREAD + " 单线程生产量: " + PER + " 容量:" + SIZE + " 数据总量:" + TOTAL_COUNT);
		 DisruptorTest.execute();
	}

	public static void println(String msg) {
		System.out.println(DateTimeFormatter.ISO_INSTANT.format(Instant.now()) + "[" + Thread.currentThread().getName() + "] " + msg);
	}
}

public class DataWorkHandler implements WorkHandler<DataEvent> {
	public AtomicLong count = new AtomicLong(0);
	public String name = null;

	public DataWorkHandler(String name) {
		this.name = name;
	}

	@Override
	public void onEvent(DataEvent event) throws Exception {
		Thread.sleep(name.contentEquals("dataEventHandler1") ? 1000 : 100);
		CompareTest.println("handlerName: " + name + " 处理的sequence:" + event.getSequence()
				+ " count:" + count.incrementAndGet() + "  Disruptor 总耗时:"
				+ (System.currentTimeMillis() - event.getStartTime()));
	}
}
  • handleEventsWith同一消息被不同handler独立消费。 此时handler处理是无序的。
disruptor.handleEventsWith(new DataEventHandler("dataEventHandler1"), new DataEventHandler("dataEventHandler2"));

  • 依赖串行.  对于同一消息前handler处理完结,后handler才处理。
disruptor.handleEventsWith(new DataEventHandler("dataEventHandler1")).then(new DataEventHandler("dataEventHandler2")).then(new DataEventHandler("dataEventHandler3"));

  • handleEventsWithWorkerPool不重复消费。 
disruptor.handleEventsWithWorkerPool(new DataWorkHandler("dataWorkHandler1"), new DataWorkHandler("dataWorkHandler2"));

  • 组合使用

disruptor.handleEventsWithWorkerPool(new DataWorkHandler("dataWorkHandler3"),new DataWorkHandler("dataWorkHandler4")).then(new DataEventHandler("dataEventHandler1"), new DataEventHandler("dataEventHandler2"));	

 

disruptor.handleEventsWith(new DataEventHandler("dataEventHandler1"), new DataEventHandler("dataEventHandler2")).thenHandleEventsWithWorkerPool(new DataWorkHandler("dataWorkHandler3"),new DataWorkHandler("dataWorkHandler4"));	

HanderThread 的 quit 和 interrupt

HanderThread 的 quit 和 interrupt

使用 Java 的时候,我们一般都是使用 interrupt 结束线程。那么使用 Android 的 HandlerThread 怎么结束一个线程呢?

 

我们知道 HanderThread 其实就是一个里吗有个 Looper 在死循环的普通 Thread

 @Override
    public void run() {
        mTid = Process.myTid();
        Looper.prepare();
        synchronized (this) {
            mLooper = Looper.myLooper();
            notifyAll();
        }
        Process.setThreadPriority(mPriority);
        onLooperPrepared();
        Looper.loop();
        mTid = -1;
    }

Looper.loop () 当然就是那个死循环了,他什么时候退出呢?

public static void loop() {
        final Looper me = myLooper();
        if (me == null) {
            throw new RuntimeException("No Looper; Looper.prepare() wasn''t called on this thread.");
        }
        final MessageQueue queue = me.mQueue;

        // Make sure the identity of this thread is that of the local process,
        // and keep track of what that identity token actually is.
        Binder.clearCallingIdentity();
        final long ident = Binder.clearCallingIdentity();

        for (;;) {
            Message msg = queue.next(); // might block
            if (msg == null) {
                // No message indicates that the message queue is quitting. 这里退出
                return;
            }

            // This must be in a local variable, in case a UI event sets the logger
            Printer logging = me.mLogging;
            if (logging != null) {
                logging.println(">>>>> Dispatching to " + msg.target + " " +
                        msg.callback + ": " + msg.what);
            }

            msg.target.dispatchMessage(msg);

            if (logging != null) {
                logging.println("<<<<< Finished to " + msg.target + " " + msg.callback);
            }

            // Make sure that during the course of dispatching the
            // identity of the thread wasn''t corrupted.
            final long newIdent = Binder.clearCallingIdentity();
            if (ident != newIdent) {
                Log.wtf(TAG, "Thread identity changed from 0x"
                        + Long.toHexString(ident) + " to 0x"
                        + Long.toHexString(newIdent) + " while dispatching to "
                        + msg.target.getClass().getName() + " "
                        + msg.callback + " what=" + msg.what);
            }

            msg.recycleUnchecked();
        }
    }

 

原来是

 Message msg = queue.next(); // might block
            if (msg == null) {
                // No message indicates that the message queue is quitting.
                return;
            }

 

那什么时候 msg = null 呢?这里的 queue 是 MessageQueue.java

Message next() {
        // Return here if the message loop has already quit and been disposed.
        // This can happen if the application tries to restart a looper after quit
        // which is not supported.
        final long ptr = mPtr;
        if (ptr == 0) {
            return null;
        }

        int pendingIdleHandlerCount = -1; // -1 only during first iteration
        int nextPollTimeoutMillis = 0;
        for (;;) {
            if (nextPollTimeoutMillis != 0) {
                Binder.flushPendingCommands();
            }

            nativePollOnce(ptr, nextPollTimeoutMillis);

            synchronized (this) {
                // Try to retrieve the next message.  Return if found.
                final long now = SystemClock.uptimeMillis();
                Message prevMsg = null;
                Message msg = mMessages;
                if (msg != null && msg.target == null) {
                    // Stalled by a barrier.  Find the next asynchronous message in the queue.
                    do {
                        prevMsg = msg;
                        msg = msg.next;
                    } while (msg != null && !msg.isAsynchronous());
                }
                if (msg != null) {
                    if (now < msg.when) {
                        // Next message is not ready.  Set a timeout to wake up when it is ready.
                        nextPollTimeoutMillis = (int) Math.min(msg.when - now, Integer.MAX_VALUE);
                    } else {
                        // Got a message.
                        mBlocked = false;
                        if (prevMsg != null) {
                            prevMsg.next = msg.next;
                        } else {
                            mMessages = msg.next;
                        }
                        msg.next = null;
                        if (false) Log.v("MessageQueue", "Returning message: " + msg);
                        return msg;
                    }
                } else {
                    // No more messages.
                    nextPollTimeoutMillis = -1;
                }

                // Process the quit message now that all pending messages have been handled.
                if (mQuitting) {
                    dispose();
                    return null;
                }

                // If first time idle, then get the number of idlers to run.
                // Idle handles only run if the queue is empty or if the first message
                // in the queue (possibly a barrier) is due to be handled in the future.
                if (pendingIdleHandlerCount < 0
                        && (mMessages == null || now < mMessages.when)) {
                    pendingIdleHandlerCount = mIdleHandlers.size();
                }
                if (pendingIdleHandlerCount <= 0) {
                    // No idle handlers to run.  Loop and wait some more.
                    mBlocked = true;
                    continue;
                }

                if (mPendingIdleHandlers == null) {
                    mPendingIdleHandlers = new IdleHandler[Math.max(pendingIdleHandlerCount, 4)];
                }
                mPendingIdleHandlers = mIdleHandlers.toArray(mPendingIdleHandlers);
            }

            // Run the idle handlers.
            // We only ever reach this code block during the first iteration.
            for (int i = 0; i < pendingIdleHandlerCount; i++) {
                final IdleHandler idler = mPendingIdleHandlers[i];
                mPendingIdleHandlers[i] = null; // release the reference to the handler

                boolean keep = false;
                try {
                    keep = idler.queueIdle();
                } catch (Throwable t) {
                    Log.wtf("MessageQueue", "IdleHandler threw exception", t);
                }

                if (!keep) {
                    synchronized (this) {
                        mIdleHandlers.remove(idler);
                    }
                }
            }

            // Reset the idle handler count to 0 so we do not run them again.
            pendingIdleHandlerCount = 0;

            // While calling an idle handler, a new message could have been delivered
            // so go back and look again for a pending message without waiting.
            nextPollTimeoutMillis = 0;
        }
    }

 

有两个地方,第一个是初始化 C++ 层对象的一个指针。第二个就是 mQuiting =true

调用 quit 的时候会导致 mQuiting = true, 那 Looper 就会退出了.HanderThread 也就退出了。此时也把 C++ 层真正的 NativeMessageQueue 对象销毁了

而 interrupt 其实是调用了 Thread.java 的 interrupt 方法,也就是 把暴力线程终止了.

 

PS: 为了提高效率,MessageQueue.java 不负责真正的队列操作, 真正的对了操作使用了 linux pipe 实现, 所以有了那个 mPtr, 它指向 Linux 层的 NativeMessageQueue. 更多请参考 http://blog.csdn.net/u010018855/article/details/50221079

 

 

今天关于Interrupt Handler使用哪个堆栈 – Linux狸奴小睡不知愁,忙添落花作锦衾的介绍到此结束,谢谢您的阅读,有关android中的runOnMainThread vs Handler-何时针对上述场景使用哪个、C3P0:java.lang.InterruptedException: sleep interrupted、Disruptor (5) - 消费方式 EventHandler & WorkHandler、HanderThread 的 quit 和 interrupt等更多相关知识的信息可以在本站进行查询。

本文标签: