精华内容
下载资源
问答
  • interrupt

    千次阅读 2021-06-07 06:38:25
    知识点:《interrupt》 收集:茹盒呜 编辑:康乃馨姐姐本知识点包括:1、1.disturb,interrupt,disrupt的区别 2、单片机中断:interrupt 0 using 1后面的using 1是... 3、c51单片机中断程序中的interrupt1,2,3是由...

    知识点:《interrupt》 收集:茹盒呜 编辑:康乃馨姐姐

    本知识点包括:1、1.disturb,interrupt,disrupt的区别 2、单片机中断:interrupt 0 using 1后面的using 1是... 3、c51单片机中断程序中的interrupt1,2,3是由什么决... 4、interrupt 的用法 5、C语言interrupt 。

    《interrupt》相关知识

    interrupt是指 你打断,插入了某项正在进行的动作 例如 一段对话 在参与者正在对话时,你打断了他们的对话 interrupt 是不礼貌的行为 例如:He interrupted the teacher's explanation and put forward his own opinion.他打断了老师的讲解并提出了自己的观点.

    disturb 着重指的是精神状态层面的被打扰,你disturb某人时,会使他人感到焦虑,打断他人的思路而使对方无法平静.My sister always disturbs me when I study.我妹妹总是在我学习时打扰我.

    interfere ,侧重指无权或未获允许而妨碍、阻扰、干涉他人之事,语气较轻.interfere是不及物动词,Intefere with sth

    另附:

    intervene :书面用词,指介入争端,进行调停,也指干涉他人之事,语气重.

    既可以做不及物动词 也可以作及物动词

    )

    知识拓展:

    1:

    1.请问interrupt跟disturb有什么区别?请举例说明.2.apologizetosb.fordoingsth.跟apologizetosb.forhavingdonesth.有什么区别?看下面两例子都是表示过去的啊?Iapologizedtoherforsteppingonherfoot.Heapologizedto

    知识要点归纳:

    1.如果两人人正在交谈,你不小心介入,用:am i interrupting in anything?如果某人正在说话,你不小心插嘴,用:i'm sorry i interrupted you.如果你正在说话,别人插嘴,用:I'd prefer if you didn't interrupt me.如果...

    2:

    disturb和interrupt的区别?

    知识要点归纳:

    interrupt 和disturb

    interrupt v. 打扰,打断,阻碍.常有 “使……停止(中断)”的意思.

    His speech was constantly interrupted by applause.

    disturb v. 打扰, 妨碍.常指失去了正常的状态或导致困难产生.

    Bad dreams disturbed her sleep.

    3:

    【interrupt和disturb有什么区别?都是打扰,有什么区别?能不能举出例句?】

    知识要点归纳:

    interrupt 和disturb

    interrupt v.打扰,打断,阻碍.常有 “使……停止(中断)”的意思.

    His speech was constantly interrupted by applause.

    disturb v.打扰,妨碍.常指失去了正常的状态或导致困难产生.

    Bad dreams disturbed her sleep.

    4:

    bother,disturb,trouble,intervene,annoy,interrupt的区别如题,然后还有哪些表干扰的词.

    知识要点归纳:

    bother 通常用于你和对方之间,比如你去见上级请示,sorry to bother you

    disturb 常用于因为你的到来,打扰了另外两人或多人的谈话或者协同做事

    trouble 用的比较随便,常表示由于你的因素给别人造成了麻烦

    intervene 是干涉的意思,口气较为强烈,且通常用于书面语,它不是打扰的意思

    annoy常常用分词形式修饰你讨厌的人,如 she is annoying since she keeps talking a lot.

    interrupt与disturb的用法相似,有个细微的区别是你加入到了被打扰方相似的谈话或者事情

    5:

    1.disturb,interrupt,disrupt的区别2.disperse,dissipate,dispel的区别3.diversion,amusement,entertainment的区别4.distrust,doubt,suspect的区别5.border,boundary,compass的区别6.resolve,solve的区别7.assess,estimate的区别8.discard,abandon

    知识要点归纳:

    To disturb在这种情况下的用法,除了指『打扰人家』,也包含了『请求帮忙』的意思,不过这种忙不能太过份,只可以是小人情(favor),不会占对方太多时间和精力.因为要打扰人家的工作,所以用to disturb的时候,必须先道歉后请求,而且态度要客气.

    如果对方在进行重要的工作,不好意思打扰,但偏偏手上的事非常要紧,就可用to interrupt(打断)这个词,例:

    I am sorry to interrupt your meeting,but there is an urgent long-distance call for Mr.Chow.(很抱歉打断你们的会议,但刚接到找周先生的紧急长途电话.)

    To disrupt(中断)和to interrupt有相近的解释,但表示干扰的程度很大,对方差不多要把手上的工作完全放下来办求问者的事,例:

    I am sorry to disrupt your work but the Marketing Director is calling an urgent meeting in 30 minutes and wants you to attend.(很抱歉打断你的工作,可是市场总监三十分钟后会召开紧急会议,)

    Dissipate通常暗含消失殆尽的意思,Dispel暗示通过或好象通过分散来驱散或赶走,disperse 消散,驱散.

    amusement=n.娱乐,消遣,乐趣/diversion=n.转移;改道;娱乐/entertainment=n.招待,招待会

    distrust〓一般用词,泛指对某人某事不信任而感到怀疑.doubt〓普通用词,多指因证据不足或仅凭证据还不能肯定而产生怀疑,多含否定意味.suspect〓指猜疑、疑心,肯定意味较多.

    border 边,边缘;边界 /boundary 分界线,边界...对照;比似 /compass 罗盘,指南针;圆规

    estimate暗示评价的主观性和不精确...assess 表示为确定某物的应税价值而作出的权威估价

    abandon 被迫放弃所感兴趣或所负责任的东西.discard v.放弃,丢弃.

    crash vi.碰撞,坠落 n.碰撞 /dash vt.使猛撞;溅 n.猛冲

    discern v.认出,发现;辨别,识别 /discover v.发现,显示...v.区别,辨别;(against)有差别地对待,歧视

    你的题目出的够戗

    猜你喜欢:

    1:1.disturb,interrupt,disrupt的区别

    提示:To disturb在这种情况下的用法,除了指『打扰人家』,也包含了『请求帮忙』的意思,不过这种忙不能太过份,只可以是小人情(favor),不会占对方太多时间和精力。因为要打扰人家的工作,所以用to disturb的时候,必须先道歉后请求,而且态度要客气...

    2:单片机中断:interrupt 0 using 1后面的using 1是...

    提示:是指这个中断函数使用单片机内存中四组工作寄存器中的哪一组,C51编译器在编译程序时会自动分配工作组,因此using x这句经常不写。

    3:c51单片机中断程序中的interrupt1,2,3是由什么决...

    提示:分别对应着5个中断源,编译时自动生成相应的中断服务入口地址: interrupt0:外部中断0 interrupt1:定时器0 interrupt2:外部中断1 interrupt3:定时器1 interrupt4:串口

    4:interrupt 的用法

    提示:现代英汉综合大辞典interrupt vt. 中断; 截断; 阻碍 打断(别人谈话); 打扰 interrupt an electric current 截断电流 He interrupted college to serve in the army. 他中断大学学业到军队去服役。 Don't interrupt me when I am busy. 我正忙的...

    5:C语言interrupt

    提示:二楼的说得很对。它是一个中断处理函数,与一般的函数的区别在于他被调用的方式。一般的函数是由其上一层函数调用而得到执行。而中断函数是是外围设备触发它执行的。比如说:SPI接收到一字节的数据、ADC采样完成、定时器发生溢出等等。一旦这些...

    展开全文
  • 关于线程的interrupt与sleep问题 目录关于线程的interrupt与sleep问题情况一:自定义线程中写interrupt与sleep       所以以后要用这种方法结束线程,编码时是先写interrupt后写sleep...

    关于线程的interrupt与sleep问题

    关于这个问题我找到了很多帖子,他们都说:

    先sleep,后才能interrupt。 sleep是阻塞,线程会暂时停在这里。interrupt 是打断。只有阻塞的线程被打断了,才会报这个异常。

    然后,我作为初学者经过实际的代码测试的时候就很蒙。我们看组代码:

    情况一:自定义线程中写interrupt与sleep

    public class SubThread4 extends Thread {
        @Override
        public void run() {
            System.out.println("当前线程的名字是:" + Thread.currentThread().getName() + System.currentTimeMillis());
            System.out.println("线程的id:" + Thread.currentThread().getId());
            System.out.println("睡眠之后:" + Thread.currentThread().getName() + System.currentTimeMillis());
            System.out.println("当前状态:" + this.isInterrupted());
            try {
                System.out.println(this.isInterrupted());
                System.out.println("打断后:"+this.isInterrupted());
                Thread.currentThread().interrupt();
                sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
                //打断后你不处理异常,继续执行循环,线程重新继续跑,所以interrupt变成false了
                //事实证明先打断后sleep才会抛出异常。。。
                //在子线程的run方法中,如果有异常要处理只能捕获处理,不能抛出处理,因为原run方法不能抛出
                //            System.out.println("调用过sleep后:"+this.isInterrupted());
                System.out.println("进入异常");
                System.out.println(this.isInterrupted());
                return;
            }
    
            System.out.println("当前状态:" + this.isInterrupted());
            System.out.println("这个线程执行完了!");
        }
    
    }
    
    

    在这里插入图片描述

    public class SubThread4 extends Thread {
        @Override
        public void run() {
            System.out.println("当前线程的名字是:" + Thread.currentThread().getName() + System.currentTimeMillis());
            System.out.println("线程的id:" + Thread.currentThread().getId());
            System.out.println("睡眠之后:" + Thread.currentThread().getName() + System.currentTimeMillis());
            System.out.println("当前状态:" + this.isInterrupted());
            try {
                System.out.println(this.isInterrupted());
                System.out.println("打断后:"+this.isInterrupted());
                sleep(3000);
                Thread.currentThread().interrupt();
            } catch (InterruptedException e) {
                e.printStackTrace();
                //打断后你不处理异常,继续执行循环,线程重新继续跑,所以interrupt变成false了
                //事实证明先打断后sleep才会抛出异常。。。
                //在子线程的run方法中,如果有异常要处理只能捕获处理,不能抛出处理,因为原run方法不能抛出
                //            System.out.println("调用过sleep后:"+this.isInterrupted());
                System.out.println("进入异常");
                System.out.println(this.isInterrupted());
                return;
            }
    
            System.out.println("当前状态:" + this.isInterrupted());
            System.out.println("这个线程执行完了!");
        }
    
    }
    

    在这里插入图片描述
          这两组代码只有sleep(3000);和Thread.currentThread().interrupt();这两行代码调换位置,这一点不同,其余部分完全一样。
          但结果好像和网上说的“先sleep,后才能interrupt,抛异常”顺序不一样啊!实际上它们是一样的,网上的分析都光分析了内部原理内部原理确实是先sleep后interrupt就会抛出异常,但他们都没说实际编码是个啥样,我也是想了半天才晕过来,在实际编程中我们的sleep调用的是Thread为我们封装好的sleep方法,也就是说sleep已经封装好了,你不可能在sleep的每一毫秒过程中都去检测或者调用interrupt方法。编码中的sleep是一个整体,它需要完全睡完,之后才能执行第二行的Thread.currentThread().interrupt();,而这个时候它都已经睡完了当然不会发生sleep中打断的情况,所以编码的这个时候 先sleep(3000);后Thread.currentThread().interrupt();是没有任何异常的。
          相反的,先使用Thread.currentThread().interrupt();将线程的中断标志调为true,这个时候我们再来写sleep(3000);它会发现中断标记已经为true了,它没法再阻塞这个线程了,就会出现异常并捕获异常。注意:这个时候它会捕获异常是不假,但它并不会返回,我们需要手动在catch中加一个return;返回并结束线程,这个也是线程的特性,它只会捕获但并不能将异常抛出后结束线程。

           所以以后要用这种方法结束线程,编码时是先写interrupt后写sleep这样才能抛异常。



    情况二:主线程中写

    这种就是大概这样你写好了自定义线程代码(就把Thread.currentThread().interrupt();删掉了interrupt();放在主线程里面):

    public class SubThread4 extends Thread {
        @Override
        public void run() {
            System.out.println("当前线程的名字是:" + Thread.currentThread().getName() + System.currentTimeMillis());
            System.out.println("线程的id:" + Thread.currentThread().getId());
            System.out.println("睡眠之后:" + Thread.currentThread().getName() + System.currentTimeMillis());
            System.out.println("当前状态:" + this.isInterrupted());
            try {
                System.out.println(this.isInterrupted());
                System.out.println("打断后:"+this.isInterrupted());
    //            Thread.currentThread().interrupt();
                sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
                //打断后你不处理异常,继续执行循环,线程重新继续跑,所以interrupt变成false了
                //事实证明先打断后sleep才会抛出异常。。。
                //在子线程的run方法中,如果有异常要处理只能捕获处理,不能抛出处理,因为原run方法不能抛出
                //            System.out.println("调用过sleep后:"+this.isInterrupted());
                System.out.println("进入异常");
                System.out.println(this.isInterrupted());
                return;
            }
    
            System.out.println("当前状态:" + this.isInterrupted());
            System.out.println("这个线程执行完了!");
        }
    
    }
    

    主方法:

    public class Test {
        public static void main(String[] args) {
            System.out.println(Thread.currentThread().getName()+" , id = "+Thread.currentThread().getId());
            SubThread4 t4 = new SubThread4();
            System.out.println("当前时间:"+System.currentTimeMillis());
            t4.start();
            t4.interrupt();
            System.out.println("睡眠之后的时间:"+System.currentTimeMillis());
        }
    }
    

    结果:
    在这里插入图片描述
          你可能觉得interrupt在线程start之后但还是抛出异常信息了,是不是编码按照先sleep后interrupt的顺序执行了呢? 错! 代码执行顺序依旧是先interrupt后sleep所以才抛得异常信息。 因为主线程里面开别的线程的方式虽然是直接调用start方法,但start方法调用后线程并没有直接执行,而是将该线程交给了线程调度器(schedule) 线程真正什么时候运行是不确定的。(但是一般都是main线程执行完才开始执行别的线程的 ,这里的一般是指JDK1.8在IDEA2018上的执行顺序,没错这就是我电脑的环境。。。XD)

          所以综上所述,这种方式,还是执行了先interrupt方法后执行了sleep方法才抛出的异常

    再换一种情况

    代码:

    public class SubThread4 extends Thread {
        @Override
        public void run() {
            System.out.println("当前线程的名字是:" + Thread.currentThread().getName() + System.currentTimeMillis());
            System.out.println("线程的id:" + Thread.currentThread().getId());
            System.out.println("睡眠之后:" + Thread.currentThread().getName() + System.currentTimeMillis());
            System.out.println("当前状态:" + this.isInterrupted());
    //        try {
    //            System.out.println(this.isInterrupted());
    //            System.out.println("打断后:"+this.isInterrupted());
                Thread.currentThread().interrupt();
    //            sleep(3000);
    //        } catch (InterruptedException e) {
    //            e.printStackTrace();
    //            //打断后你不处理异常,继续执行循环,线程重新继续跑,所以interrupt变成false了
    //            //事实证明先打断后sleep才会抛出异常。。。
    //            //在子线程的run方法中,如果有异常要处理只能捕获处理,不能抛出处理,因为原run方法不能抛出
    //            //            System.out.println("调用过sleep后:"+this.isInterrupted());
                System.out.println("进入异常");
                System.out.println(this.isInterrupted());
                return;
    //        }
    
            System.out.println("当前状态:" + this.isInterrupted());
            System.out.println("这个线程执行完了!");
        }
    
    }
    

    主线程:

    public class Test {
        public static void main(String[] args) {
            System.out.println(Thread.currentThread().getName()+" , id = "+Thread.currentThread().getId());
            SubThread4 t4 = new SubThread4();
            System.out.println("当前时间:"+System.currentTimeMillis());
            t4.start();
    //        try {
    //            sleep(4000);
    //        } catch (InterruptedException e) {
    //            e.printStackTrace();
    //        }
            Thread.currentThread().interrupt();
            try {
                sleep(4000);
            } catch (InterruptedException e) {
                e.printStackTrace();
                return;
            }
    
    //        t4.interrupt();
            System.out.println("睡眠之后的时间:"+System.currentTimeMillis());
        }
    }
    

    结果:
    在这里插入图片描述
    我们可以很明显的看到主线程被打断了
    在这里插入图片描述
    主线程中这一句代码没有执行。
          但子线程执行了,你可能会在一开始觉得子线程永远在主线程运行完才执行,主线程要停了子线程就不执行了。

          但子线程依旧执行了,虽然主线程被打断睡眠抛出了异常还调用了return将主线程结束,线程调度器在主线程结束前执行了子线程。说明线程执行顺序不确定,且在编码中先写interrupt后写sleep才能抛出异常实现想要的结果。

    展开全文
  • 概述Thread提供了interrupt方法,中断线程的执行:如果线程堵塞在object.wait、Thread.join和Thread.sleep,将会抛出InterruptedException,同时清除线程的中断状态;如果线程堵塞在java.nio.channels....

    概述

    Thread提供了interrupt方法,中断线程的执行:

    如果线程堵塞在object.wait、Thread.join和Thread.sleep,将会抛出InterruptedException,同时清除线程的中断状态;

    如果线程堵塞在java.nio.channels.InterruptibleChannel的IO上,Channel将会被关闭,线程被置为中断状态,并抛出java.nio.channels.ClosedByInterruptException;

    如果线程堵塞在java.nio.channels.Selector上,线程被置为中断状态,select方法会马上返回,类似调用wakeup的效果;

    public void interrupt() {

    if (this != Thread.currentThread())

    checkAccess();

    synchronized (blockerLock) {

    Interruptible b = blocker;

    if (b != null) {

    interrupt0(); // Just to set the interrupt flag

    b.interrupt(this);

    return;

    }

    }

    interrupt0();

    }

    源码实现

    之前在分析Thread.start的时候曾经提到,JavaThread有三个成员变量:

    //用于synchronized同步块和Object.wait()

    ParkEvent * _ParkEvent ;

    //用于Thread.sleep()

    ParkEvent * _SleepEvent ;

    //用于unsafe.park()/unpark(),供java.util.concurrent.locks.LockSupport调用,

    //因此它支持了java.util.concurrent的各种锁、条件变量等线程同步操作,是concurrent的实现基础

    Parker* _parker;

    初步猜测interrupt实现应该与此有关系;

    interrupt方法的源码也在jvm.cpp文件:

    JVM_ENTRY(void, JVM_Interrupt(JNIEnv* env, jobject jthread))

    JVMWrapper("JVM_Interrupt");

    // Ensure that the C++ Thread and OSThread structures aren't freed before we operate

    oop java_thread = JNIHandles::resolve_non_null(jthread);

    MutexLockerEx ml(thread->threadObj() == java_thread ? NULL : Threads_lock);

    // We need to re-resolve the java_thread, since a GC might have happened during the

    // acquire of the lock

    JavaThread* thr = java_lang_Thread::thread(JNIHandles::resolve_non_null(jthread));

    if (thr != NULL) {

    Thread::interrupt(thr);

    }

    JVM_END

    JVM_Interrupt对参赛进行了校验,然后直接调用Thread::interrupt:

    void Thread::interrupt(Thread* thread) {

    trace("interrupt", thread);

    debug_only(check_for_dangling_thread_pointer(thread);)

    os::interrupt(thread);

    }

    Thread::interrupt调用os::interrupt方法实现,os::interrupt方法定义在os_linux.cpp:

    void os::interrupt(Thread* thread) {

    assert(Thread::current() == thread || Threads_lock->owned_by_self(),

    "possibility of dangling Thread pointer");

    //获取系统native线程对象

    OSThread* osthread = thread->osthread();

    if (!osthread->interrupted()) {

    osthread->set_interrupted(true);

    //内存屏障,使osthread的interrupted状态对其它线程立即可见

    OrderAccess::fence();

    //前文说过,_SleepEvent用于Thread.sleep,线程调用了sleep方法,则通过unpark唤醒

    ParkEvent * const slp = thread->_SleepEvent ;

    if (slp != NULL) slp->unpark() ;

    }

    //_parker用于concurrent相关的锁,此处同样通过unpark唤醒

    if (thread->is_Java_thread())

    ((JavaThread*)thread)->parker()->unpark();

    //synchronized同步块和Object.wait() 唤醒

    ParkEvent * ev = thread->_ParkEvent ;

    if (ev != NULL) ev->unpark() ;

    }

    由此可见,interrupt其实就是通过ParkEvent的unpark方法唤醒对象;另外要注意:

    object.wait、Thread.sleep和Thread.join会抛出InterruptedException并清除中断状态;

    Lock.lock()方法不会响应中断,Lock.lockInterruptibly()方法则会响应中断并抛出异常,区别在于park()等待被唤醒时lock会继续执行park()来等待锁,而 lockInterruptibly会抛出异常;

    synchronized被唤醒后会尝试获取锁,失败则会通过循环继续park()等待,因此实际上是不会被interrupt()中断的;

    一般情况下,抛出异常时,会清空Thread的interrupt状态,在编程时需要注意;

    网络相关的中断

    之前的interrupt方法有这么一段:

    private volatile Interruptible blocker;

    private final Object blockerLock = new Object();

    synchronized (blockerLock) {

    Interruptible b = blocker;

    if (b != null) {

    interrupt0(); // Just to set the interrupt flag

    b.interrupt(this);

    return;

    }

    }

    其中blocker是Thread的成员变量,Thread提供了blockedOn方法可以设置blocker:

    void blockedOn(Interruptible b) {

    synchronized (blockerLock) {

    blocker = b;

    }

    }

    如果一个nio通道实现了InterruptibleChannel接口,就可以响应interrupt()中断,其原理就在InterruptibleChannel接口的抽象实现类AbstractInterruptibleChannel的方法begin()中:

    protected final void begin() {

    if (interruptor == null) {

    interruptor = new Interruptible() {

    public void interrupt(Thread target) {

    synchronized (closeLock) {

    if (!open)

    return;

    open = false;

    interrupted = target;

    try {

    AbstractInterruptibleChannel.this.implCloseChannel();

    } catch (IOException x) { }

    }

    }};

    }

    blockedOn(interruptor);//设置当前线程的blocker为interruptor

    Thread me = Thread.currentThread();

    if (me.isInterrupted())

    interruptor.interrupt(me);

    }

    protected final void end(boolean completed)

    throws AsynchronousCloseException

    {

    blockedOn(null);//设置当前线程的blocker为null

    Thread interrupted = this.interrupted;

    //如果发生中断,Thread.interrupt方法会调用Interruptible的interrupt方法,

    //设置this.interrupted为当前线程

    if (interrupted != null && interrupted == Thread.currentThread()) {

    interrupted = null;

    throw new ClosedByInterruptException();

    }

    if (!completed && !open)

    throw new AsynchronousCloseException();

    }

    //Class java.nio.channels.Channels.WritableByteChannelImpl

    public int write(ByteBuffer src) throws IOException {

    ......

    try {

    begin();

    out.write(buf, 0, bytesToWrite);

    finally {

    end(bytesToWrite > 0);

    }

    ......

    }

    //Class java.nio.channels.Channels.ReadableByteChannelImpl

    public int read(ByteBuffer dst) throws IOException {

    ......

    try {

    begin();

    bytesRead = in.read(buf, 0, bytesToRead);

    finally {

    end(bytesRead > 0);

    }

    ......

    }

    以上述代码为例,nio通道的ReadableByteChannel每次执行阻塞方法read()前,都会执行begin(),把Interruptible回调接口注册到当前线程上。当线程中断时,Thread.interrupt()触发回调接口Interruptible关闭io通道,导致read方法返回,最后在finally块中执行end()方法检查中断标记,抛出ClosedByInterruptException;

    Selector的实现类似:

    //java.nio.channels.spi.AbstractSelector

    protected final void begin() {

    if (interruptor == null) {

    interruptor = new Interruptible() {

    public void interrupt(Thread ignore) {

    AbstractSelector.this.wakeup();

    }};

    }

    AbstractInterruptibleChannel.blockedOn(interruptor);

    Thread me = Thread.currentThread();

    if (me.isInterrupted())

    interruptor.interrupt(me);

    }

    protected final void end() {

    AbstractInterruptibleChannel.blockedOn(null);

    }

    //sun.nio.ch.class EPollSelectorImpl

    protected int doSelect(long timeout) throws IOException {

    ......

    try {

    begin();

    pollWrapper.poll(timeout);

    } finally {

    end();

    }

    ......

    }

    可以看到当发生中断时会调用wakeup方法唤醒poll方法,但并不会抛出中断异常;

    展开全文
  • kvm post interrupt

    2021-05-22 00:16:15
    点击蓝字关注我们1post interruptpost interrupt是intel提供的一种硬件机制,不用物理cpu从root模式exit到non-root模式就能把虚拟中断注入到no...

    点击蓝字

    关注我们

    1

    post interrupt

    post interrupt是intel提供的一种硬件机制,不用物理cpu从root模式exit到non-root模式就能把虚拟中断注入到non-root模式里,大概实现就是把虚拟中断写到post interrupt descriptor,预定义了一个中断号,然后给non-root模式下的cpu发送这个中断,non-root模式下cpu收到这个中断触发对virtual-apic page的硬件模拟,从post interrupt descriptor取出虚拟中断更新到virtual-apic page中,虚拟机中读virtual-access page,就能取到虚拟中断,处理中断,然后写EOI,触发硬件EOI virtulization,就能把virtual-apic page和post interrupt descriptor中数据清除。

    post interrupt descriptor的格式如下:

    PIR总共256位,一位代表一个虚拟中断。ON代表预先定义的中断已经发出,如果已经为1就不要再发预先定义的中断了。SN代表不要再发中断。NV就是预先定义好的那个中断号,NDST就是物理CPU的local apic id。

    2

    vt-x post interrupt

    VMCS中增加如下字段控制post interrupt。

    kvm用post interrupt模式给vcpu注入中断,kvm修改这个vcpu的post interrupt descriptor,然后给这个vcpu所运行的物理cpu发送中断号是post interrupt notification vector的中断。kvm只用到了post interrupt descriptor中的ON,用到的notification vector存放在VMCS中而不是post interrupt descriptor中,主要是kvm运行在另一个物理cpu上,一个vcpu有没有运行,运行在哪个物理cpu上,这个vcpu可不可以接收中断,kvm很好判断,如果没有运行或者不能接收中断kvm在把虚拟中断存放在其它地方。


    3

    vt-d post interrupt

    IOMMU硬件单元也可以借用post interrupt机制把passthrough设备产生的中断直接投递到虚拟机中,不需要虚拟机exit出来,不需要VMM软件介入,性能非常高。这种情况设备产生的中断从原来interrupt remapping格式变成post interrupt格式,IRTE内容也变了,它中存放post interrupt descriptor的地址和虚拟中断vector,物理中断到了IOMMU,IOMMU硬件单元直接IRTE中虚拟中断vector写到post interrupt descriptor中pir对应的位,然后给vcpu所在的物理cpu发送一个中断,中断号就是post interrupt descriptor中的NV。

    一个passthrough给虚拟机的外设,虚拟机里driver给外设分配虚拟中断,qemu拦截到对外设pci config space的写,然后把虚拟中断更新到kvm的irq routing entry中,kvm再调用update_pi_irte把post interrupt descriptor地址和虚拟中断号更新到IRTE中。

    update_pi_irte
      └─irq_set_vcpu_affinity
           └─intel_ir_set_vcpu_affinity
                 └─modify_irte

    vt-x posted interrupt就是另一个CPU更新了vcpu的post interrupt descriptor,发送一个ipi给vcpu运行的物理CPU。vt-d posted interrupt就是IOMMU硬件单元更新了vcpu的post interrupt descriptor。vt-x和vt-d post interrupt都不会导致vcpu运行的物理CPU从non-root模式exit到root模式,而且能把vcpu的中断注入到guest。但vt-d相比vt-x就弱智多了,一个vcpu有没有运行,运行在哪个物理cpu上,这个vcpu可不可以接收中断,或者vcpu从一个物理cpu迁移到另一个物理cpu,vt-d IOMMU都不能自己判断,只能通过kvm告诉它,所以kvm就把这些信息写到post interrupt descriptor的其它位中,IOMMU来读,这些位就是SN,NDST和NV。

    vcpu转换为运行状态,vmx_vcpu_pi_load清除SN,更新NDST。

    vcpu_load
      └─preempt_notifier_register
    
    context_switch
      └─finish_task_switch
          └─fire_sched_in_preempt_notifiers
              └─ __fire_sched_in_preempt_notifiers
                   └─kvm_sched_in
                       └─kvm_arch_vcpu_load
                          └─kvm_x86_vcpu_load
                               └─vmx_vcpu_pi_load

    vcpu暂时挂起,设置SN。

    vmx_vcpu_put
        └─vmx_vcpu_pi_put

    虚拟机执行hlt指令vcpu暂停,保留原先运行的物理cpu到NDST,设置NV为wakeup vector

    vcpu_block
        └─vmx_pre_block
             └─pi_pre_block

    如果此时IRTE中URG为1,IOMMU就给物理cpu发送wakeup vector,pi_wakeup_handler让vcpu开始运行。

    DEFINE_IDTENTRY_SYSVEC(sysvec_kvm_posted_intr_wakeup_ipi)
    {
    	ack_APIC_irq();
    	inc_irq_stat(kvm_posted_intr_wakeup_ipis);
    	kvm_posted_intr_wakeup_handler();
    }
    kvm_set_posted_intr_wakeup_handler(pi_wakeup_handler);

    vcpu开始运行,更新NDST,理想NV为post interrupt vector。

    vmx_post_block           
      └─pi_post_block

    4

    pv ipi

    虚拟机中一个vcpu要向另一个vcpu发送ipi或者向其它vcpu广播ipi,怎么利用post interrupt?

    首先源vcpu需要把ipi的目的vcpu的local apic id写到apic寄存器,再写icr寄存器,写icr寄存器就会导致vcpu exit,然后kvm就可以利用vt-x posted interrupt把虚拟中断注入到另一个vcpu。如果是广播ipi,那么源vcpu要exit出来很多次。

    kvm_lapic_reg_write->kvm_apic_send_ipi

    所以腾讯云李万鹏就想了招,通过hypercall传bitmap一次把所有目的vcpu都传出来,这样源vcpu就可以少exit出来几次。

    kvm_emulate_hypercall->kvm_pv_send_ipi

    有些虚拟机中的业务会大量用到ipi,导致虚拟机exit出来很多很多次,性能影响太大。有人就想到把源vcpu所运行的物理cpu的lapic的icr寄存器透传给vcpu,把其它vcpu的post interrupt descriptor也透传给虚拟机源vcpu,源vcpu要给目的vcpu发送ipi,源vcpu修改目的vcpu的post interrupt descriptor,源vcpu给真正的硬件寄存器icr写post interrupt notification vector,这样源vcpu不用exit出来。问题就是有点不安全,一个有问题的虚拟机可以频繁给其它物理cpu发送ipi,造成其它物理cpu ipi DDOS攻击,私有云可以用,公有云不行。

    END

    查看历史文章

    Kubevirt在360的探索之路(K8S接管虚拟化)
    如何提高大规模正则匹配的效能
    360Stack裸金属服务器部署实践

    360技术公众号

    技术干货|一手资讯|精彩活动

    扫码关注我们

    展开全文
  • 7.中断门(Interrupt Gate)

    千次阅读 2021-09-20 19:06:17
    0.Interrupt Descriptor Table <1>.Windbg查找IDT <2>.代码查看IDT 1.中断门描述符 2.中断门执行 <1>.中断门执行流程 <2>.中断门堆栈 <3>.中断门返回 3.中断门示例 <1>...
  • Java Interrupt

    2021-03-27 18:12:52
    本文中,我们主要介绍一下 Java 提供的 Interrupt 机制的常见使用方法,以及 Interrupt 的实现。 Interrupt 在 Java 中,如果我们想要操作一个线程的执行状态,可以直接调用 Thread::stop 停止它的运行,但是这样...
  • 线程的打断(interrupt) interrupt相关的三个方法: interrupt只是设置标志位,并不是真的断开线程 public void interrupt() //t.interrupt() 打断t线程(设置t线程某给标志位f=true,并不是打断线程的运行) ...
  • 为了低延时,会支持NVIC(Nested vectored interrupt controller) 有些要从DeepSleep唤醒CPU,则要支持WIC(Wakeup interrupt controller) 一般中断向量表放在代码code的前面一段,或者flash低地址部分。 比如...
  • C语言在8051单片机上的扩展(interrupt、using关键字的用法)直接访问寄存器和端口定义sfr P0 0x80sfrP1 0x81sfrADCON; 0xDEsbit EA0x9F操作ADCON = 0x08;P1 = 0xFF;io_status = P0 ;EA = 1;在使用了interrupt 1 ...
  • Java线程之interrupt方法

    2021-03-18 22:51:32
    1.背景 2.Java线程中interrupt方法 2.1 interrupt 2.2 isinterrupted 2.3interrupted 3.两阶段终止模式 4.总结
  • All experienced embedded system designers know that interrupt latency is one of the key characteristics of a microcontrolller, and are aware that this is crucial for many applications with real time ...
  • 先看收集了别人的文章,全面的了解下java的中断:中断线程线程的thread.interrupt()方法是中断线程,将会设置该线程的中断状态位,即设置为true,中断的结果线程是死亡、还是等待新的任务或是继续运行至下一步,就取...
  • C51 interrupt 中断

    2021-04-01 19:07:40
    1、中断源与标记位 ----引起CPU中断的... } } void ext0() interrupt 0 //中断服务程序,‘ 0 ’是外部中断0入口序号 { a=0x0f; } 参考文献: [1]王云. 51单片机C语言程序设计教程. 北京:人名邮电出版社,2018.11
  • 一、interrupt() 说明interrupt()的作用是中断本线程。本线程中断自己是被允许的;其它线程调用本线程的interrupt()方法时,会通过checkAccess()检查权限。这有可能抛出SecurityException异常。如果本线程是处于阻塞...
  • void timer0 (void) interrupt 1 using 2 { if (++interruptcnt == 4000) { second++; interruptcnt = 0; } } interrupt 关键词后跟一个整数,表示中断号,取值范围0-31。中断号必须为常数,不允许...
  • C语言中的interrupt是怎么回事來源:互聯網2009-07-12 06:18:42評論分類: 電腦/網絡 >> 程序設計 >> 其他編程語言問題描述:今天看以程序,看到void interrupt ( *oldhandler)(__CPPARGS);搞不明白是怎么...
  • Linux中断(interrupt)机制1 中断是什么?Linux 内核需要对连接到计算机上的所有硬件设备进行管理,毫无疑问这是它的份内事。如果要管理这些设备,首先得和它们互相通信才行,一般有两种方案可实现这种功能:轮询...
  • C语言应用-6-Interrupt第 6 章 中断系统的 C 语言程序设计526.1 中断系统 526.1.1 中断源 526.1.2 中断优先级和中断入口地址546.2 中断控制 546.2.1 中断控制的寄存器 546.2.2 中断响应过程566.3 中断控制的相关 C ...
  • C语言在8051单片机上的扩展(interrupt、using关键字的用法)直接访问寄存器和端口定义sfrP0 0x80sfrP1 0x81sfrADCON; 0xDEsbit EA0x9F操作ADCON = 0x08 ;P1= 0xFF;io_status = P0 ;EA= 1;在使用了interrupt 1关键字...
  • 接收满中断意思就是接收的fifo里面数据满了多少就触发中断 发送空中断就是先发送数据到fifo里面,然后数不断被搬运走,然后fifio里面数据不断减少,减少到所触发的阈值
  • 其实原因就两句话: 不加sleep时,调用thread.interrupt()时可能线程还活着 加上sleep时,调用thread.interrupt()时线程已经结束了,而对于方法interrupt()不会修改一个已经结束的线程的中断标志位。 其实我们可以...
  • 6)interrupt方法 interrupt,顾名思义,即中断的意思。单独调用interrupt方法可以使得处于阻塞状态的线程抛出一个异常,也就说,它可以用来中断一个正处于阻塞状态的线程;另外,通过interrupt方法和isInterrupted...
  • 关于Thread的interrupt

    2021-07-04 15:28:55
    关于Thread的interrupt Thread的interrupt方法会引发线程中断。 主要有以下几个作用: 如Object的wait方法,Thread的sleep等等这些能够抛出InterruptedException异常的方法,在遇到调用对应线程的interrupt方法...
  • } } catch (InterruptedException e) {} } public void cancel() { this.interrupt(); } 但线程不会终止.我使用调试器并发现在命令this.interrupt()之后,线程没有被中断(我在表达式上监视this.isInterrupted()并且...
  • itop4412 设备树 Interrupt

    2021-05-24 20:05:59
    itop4412 设备树 Interrupt 设备树配置 在这个目录下面添加:arch/arm/boot/dts/exynos4412-itop-elite.dts text_key { compatible = "key_text"; pinctrl-names = "default"; pinctrl-0 = <&key_...
  • 有问题的interrupt package com.xinyu.test; public class TestInterrupt { public static void main(String[] args) { TestThread testThread = new TestThread(); testThread.start(); try { Thread.sleep...
  • Java面试-interrupt

    2021-03-01 06:11:46
    我们都知道,Java中停止一个线程不能用stop,因为stop会瞬间强行停止一个线程...interrupt相关的方法Java中和interrupt相关的方法有三个public boolean isInterrupted()public void interrupt()public static boolea...
  • 基于上面的理由,Java提供了新的中断机制(interrupt),其他线程调用想要终止线程的interrupt()方法. 这个时候线程会根据自己的状态做出响应: 如果线程处于阻塞状态(sleep,wait,join),则线程会抛出...
  • } } 解决方法: When a thread checks for an interrupt by invoking the static method Thread.interrupted, interrupt status is cleared. The non-static isInterrupted method, which is used by one thread to ...
  • } } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 BLOCKED 如果线程在等待锁,对线程对象调用interrupt()只是会设置线程的中断标志位,线程依然会处于BLOCKED状态,也就是说,interrupt...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 222,346
精华内容 88,938
关键字:

interrupt

友情链接: 1、不同充磁方式.rar