【问题标题】:Java signal handling and then return to main programJava信号处理然后返回主程序
【发布时间】:2013-03-20 23:48:05
【问题描述】:

MI有一个程序以for循环开头,它旋转了10次,一个循环持续一秒钟。我需要处理一个信号(CTRL+C),在处理它时,它应该做它自己的 for 循环,在它停止之后,我应该返回到主循环。我已经设法完成了上面的几乎所有事情,但循环不会单独执行。他们并行进行。希望你能帮忙...谢谢:)

顺便说一句,我的代码是:

import sun.misc.Signal;
import sun.misc.SignalHandler;

public class MySig {

    public static void shhh(int s){ //s -> seconds :)
        s = s*1000;
        try{
            Thread.sleep(s);
        }catch(InterruptedException e){
            System.out.println("Uh-oh :(");
        }
    }

  public static void main(String[] args){
      Signal.handle(new Signal("INT"), new SignalHandler () {
      public void handle(Signal sig) {
      for(int i=0; i<5; i++){
        System.out.println("+");
        shhh(1);
    }
    }
    });
    for(int i=0; i<10; i++) {
      shhh(1);
      System.out.println(i+"/10");
    }
  } 
}

【问题讨论】:

  • 我真的不明白你的问题和你的代码应该做什么?
  • 这是一个大学“家庭作业”...我的程序应该处理当我在循环工作时按 CTRL+C 时出现的信号,为该信号运行另一个循环,然后所有信号都已处理完毕,返回主循环并继续……如果我不够清楚,我很抱歉

标签: java signals sigint


【解决方案1】:

对,根据文档,SignalHandler 在单独的线程中执行:

...当 VM 接收到一个信号时,特殊的 C 信号处理程序会创建一个 运行已注册的新线程(优先级为 Thread.MAX_PRIORITY) Java 信号处理程序..

如果您想在处理程序执行时停止主循环,您可以添加锁定机制,如下所示:

private static final ReentrantLock lock = new ReentrantLock(true);
private static AtomicInteger signalCount = new AtomicInteger(0);

public static void shhh(int s) { // s -> seconds :)
    s = s * 1000;
    try {
        System.out.println(Thread.currentThread().getName() + " sleeping for "
                + s + "s...");
        Thread.sleep(s);
    } catch (InterruptedException e) {
        System.out.println("Uh-oh :(");
    }
}

public static void main(String[] args) throws Exception {
    Signal.handle(new Signal("INT"), new SignalHandler() {
        public void handle(Signal sig) {
            // increment the signal counter
            signalCount.incrementAndGet();
            // Acquire lock and do all work
            lock.lock();
            try {
                for (int i = 0; i < 5; i++) {
                    System.out.println("+");
                    shhh(1);
                }
            } finally {
                // decrement signal counter and unlock
                signalCount.decrementAndGet();
                lock.unlock();
            }
        }

    });
    int i = 0;
    while (i < 10) {
        try {
            lock.lock();
            // go back to wait mode if signals have arrived
            if (signalCount.get() > 0)
                continue;
            System.out.println(i + "/10");
            shhh(1);
            i++;
        } finally {
            // release lock after each unit of work to allow handler to jump in
            lock.unlock();
        }
    }
}

可能会有更好的锁定策略。

【讨论】:

  • 这很好,但是如果我在处理一个信号的同时按 CTRL+C,它会将第一个信号处理到最后,在主循环中循环一次,然后处理第二个信号。 …我忘了在上面提到它......对不起
  • 我编辑了上面的代码来实现这个目标,虽然它绝对不优雅。基本上,我只是引入了一个新的信号计数器,并让主线程检查该计数器,如果计数器 > 0 则返回等待模式
猜你喜欢
  • 2012-01-08
  • 2021-11-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-10-24
  • 1970-01-01
  • 1970-01-01
  • 2019-12-13
相关资源
最近更新 更多