0

MI have a program that starts with for loop and it spins for 10 times, and one loop lasts one second. I need to handle a signal (CTRL+C) and while handling it, it should do it's own for loop, and after it stops, then I should return to the main loop. I've managed to do almost everything above, but the loops don't execute separately. They do it parallel. Hope you can help... thanks :)

BTW, my code is:

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");
    }
  } 
}
almalki
  • 4,595
  • 26
  • 30
dmacan23
  • 765
  • 1
  • 9
  • 17
  • I really don't understand your question neither what your code suppose to do? – Smit Mar 21 '13 at 00:04
  • It is a college "homework"... My program is supposed to handle the signal that comes when I press CTRL+C while the loop is working, run the other loop for that signal, and after all signals have been handled, just return to the main loop and continue... I'm sorry if I wasn't clear enough – dmacan23 Mar 21 '13 at 16:57

1 Answers1

1

Right, according to the docs, SignalHandler is executed in a separate thread:

...when the VM receives a signal, the special C signal handler creates a new thread (at priority Thread.MAX_PRIORITY) to run the registered Java signal handler..

If you want to stop your main loop while the handler is executing, you can add a locking mechanism, something like this:

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();
        }
    }
}

There might be a better locking strategy.

Blake
  • 581
  • 4
  • 14
  • This is great, but then if I press CTRL+C while handling one signal already, it handles the first signal to the end, loops one time through the main loop, and then handles the second signal... What I would want is that it starts handling second signal as soon as I send it, then handles the previous one, and so on until all the signals have been handled, and then return to the main loop... I know, I forgot to mention it above... sorry – dmacan23 Mar 21 '13 at 16:51
  • I edited the code above to accomplish that goal although it definitely doesn't feel elegant. Basically, I just introduced a new signal counter and have the main thread check that counter and go back into wait mode if the counter > 0 – Blake Mar 22 '13 at 03:48