Re: Catching control-C

2009-07-15 Thread MCIPERF
On Jul 9, 7:28 pm, Miles Kaufmann mile...@umich.edu wrote:
 On Jul 9, 2009, at 9:20 AM, Lie Ryan wrote:

  Michael Mossey wrote:
  I want to understand better what the secret is to responding to a
  ctrl-C in any shape or form.

  Are you asking: when would the python interpreter process
  KeyboardInterrupt?
  ...
  In single threaded python program, the currently running thread is
  always the main thread (which can handle KeyboardInterrupt). I believe
  SIGINT is checked at every ticks. But SIGINT cannot interrupt atomic
  operations (i.e. it cannot interrupt long operations that takes a  
  single
  tick).

 Some otherwise atomic single-bytecode operations (like large integer  
 arithmetic) do manual checks for whether signals were raised (though  
 that won't help at all if the operation isn't on the main thread).

  I believe a tick in python is equivalent to a single bytecode, but
  please correct me if I'm wrong.

 Not all opcodes qualify as a tick.  In general, those opcodes that  
 cause control to remain in the eval loop (and not make calls to other  
 Python or C functions) don't qualify as ticks (but there are  
 exceptions, e.g. so that while True: pass is interruptible).  In  
 Python/ceval.c: PyEval_EvalFrameEx(), those opcodes that don't end in  
 goto fast_next_opcode are ticks.

 Please correct me if _I'm_ wrong! :)
 -Miles

You don't need to do I/O.

This works:

try:
   process_forever()
except KeyboardInterrupt:
   save critical stuff
   write nice messages

I often wrap a large computational task like this, with the idea that
the exception can let me exit safely, in my case by writing restart
parameters and printing a summary pf progress to date.

Gerry
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Catching control-C

2009-07-09 Thread Lie Ryan
Michael Mossey wrote:
 On Jul 6, 2:47 pm, Philip Semanchuk phi...@semanchuk.com wrote:
 On Jul 6, 2009, at 5:37 PM, Michael Mossey wrote:

 What is required in a python program to make sure it catches a  
 control-
 c on the command-line? Do some i/o? The OS here is Linux.
 You can use a try/except to catch a KeyboardInterrupt exception, or  
 you can trap it using the signal 
 module:http://docs.python.org/library/signal.html

 You want to trap SIGINT.

 HTH
 Philip
 
 Thanks to both of you. However, my question is also about whether I
 need to be doing i/o or some similar operation for my program to
 notice in any shape or form that Control-C has been pressed. In the
 past, I've written Python programs that go about their business
 ignoring Ctrl-C. Other programs respond to it immediately by exiting.
 I think the difference is that the latter programs are doing i/o. But
 I want to understand better what the secret is to responding to a
 ctrl-C in any shape or form.
 
 For example, does trapping SIGINT always work, regardless of what my
 process is doing?
 
 Thanks,
 Mike

Are you asking: when would the python interpreter process
KeyboardInterrupt?

In a multi threaded python program (where KeyboardInterrupt doesn't
always work), only the main thread can process KeyboardInterrupt; thus
the main thread must regain control before the interrupt is raised.
Normally, python will context switch (i.e. thread switch) every 100
interpreter ticks, but when the interpreter received a SIGINT, the
interpreter will try to context switch as fast as it can (every tick) to
allow the main thread to regain control. So the answer is in
multithreaded python program: when the main thread regains control

In single threaded python program, the currently running thread is
always the main thread (which can handle KeyboardInterrupt). I believe
SIGINT is checked at every ticks. But SIGINT cannot interrupt atomic
operations (i.e. it cannot interrupt long operations that takes a single
tick).

An example, where python have difficulties processing KeyboardInterrupt:
 print 'foo'*1000
...foofoofoo...
because printing a string is an atomic operation

I believe a tick in python is equivalent to a single bytecode, but
please correct me if I'm wrong.
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Catching control-C

2009-07-09 Thread Miles Kaufmann

On Jul 9, 2009, at 9:20 AM, Lie Ryan wrote:


Michael Mossey wrote:

I want to understand better what the secret is to responding to a
ctrl-C in any shape or form.


Are you asking: when would the python interpreter process
KeyboardInterrupt?
...
In single threaded python program, the currently running thread is
always the main thread (which can handle KeyboardInterrupt). I believe
SIGINT is checked at every ticks. But SIGINT cannot interrupt atomic
operations (i.e. it cannot interrupt long operations that takes a  
single

tick).


Some otherwise atomic single-bytecode operations (like large integer  
arithmetic) do manual checks for whether signals were raised (though  
that won't help at all if the operation isn't on the main thread).



I believe a tick in python is equivalent to a single bytecode, but
please correct me if I'm wrong.


Not all opcodes qualify as a tick.  In general, those opcodes that  
cause control to remain in the eval loop (and not make calls to other  
Python or C functions) don't qualify as ticks (but there are  
exceptions, e.g. so that while True: pass is interruptible).  In  
Python/ceval.c: PyEval_EvalFrameEx(), those opcodes that don't end in  
goto fast_next_opcode are ticks.


Please correct me if _I'm_ wrong! :)
-Miles

--
http://mail.python.org/mailman/listinfo/python-list


Re: Catching control-C

2009-07-08 Thread Nick Craig-Wood
Steven D'Aprano st...@remove-this-cybersource.com.au wrote:
  On Mon, 06 Jul 2009 15:02:26 -0700, Michael Mossey wrote:
 
  On Jul 6, 2:47 pm, Philip Semanchuk phi...@semanchuk.com wrote:
  On Jul 6, 2009, at 5:37 PM, Michael Mossey wrote:
 
   What is required in a python program to make sure it catches a
   control-
   c on the command-line? Do some i/o? The OS here is Linux.
 
  You can use a try/except to catch a KeyboardInterrupt exception, or you
  can trap it using the signal
  module:http://docs.python.org/library/signal.html
 
  You want to trap SIGINT.
 
  HTH
  Philip
  
  Thanks to both of you. However, my question is also about whether I need
  to be doing i/o or some similar operation for my program to notice in
  any shape or form that Control-C has been pressed. In the past, I've
  written Python programs that go about their business ignoring Ctrl-C.
 
  I bet that somewhere in your code you have something like:
 
 
  for x in really_big_list:
  try:
  long_running_process(x)
  except:
  continue
 
 
  If that's what you're doing, stop! The correct way is:
 
 
  for x in really_big_list:
  try:
  long_running_process(x)
  except Exception:
  # Let KeyboardInterrupt and SystemExit through.
  continue

Note that it is a relatively recent change (in python 2.5) which made
KeyboardInterrupt not a child of Exception

n...@dogger:~$ python2.4
Python 2.4.6 (#2, Feb 17 2009, 20:01:48)
[GCC 4.3.3] on linux2
Type help, copyright, credits or license for more information.
Loaded customisations from '/home/ncw/.pystartup'
 isinstance(KeyboardInterrupt(), Exception)
True


n...@dogger:~$ python2.5
Python 2.5.4 (r254:67916, Feb 17 2009, 20:16:45)
[GCC 4.3.3] on linux2
Type help, copyright, credits or license for more information.
Loaded customisations from '/home/ncw/.pystartup'
 isinstance(KeyboardInterrupt(), Exception)
False


  for x in really_big_list:
  try:
  long_running_process(x)
  except (KeyboardInterrupt, SystemExit):
  print User requested exit... shutting down now
  cleanup()
  raise
  except Exception:
  continue

That is the backwards compatible way

-- 
Nick Craig-Wood n...@craig-wood.com -- http://www.craig-wood.com/nick
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Catching control-C

2009-07-07 Thread Simon Forman
On Jul 6, 6:02 pm, Michael Mossey michaelmos...@gmail.com wrote:
 On Jul 6, 2:47 pm, Philip Semanchuk phi...@semanchuk.com wrote:

  On Jul 6, 2009, at 5:37 PM, Michael Mossey wrote:

   What is required in a python program to make sure it catches a  
   control-
   c on the command-line? Do some i/o? The OS here is Linux.

  You can use a try/except to catch a KeyboardInterrupt exception, or  
  you can trap it using the signal 
  module:http://docs.python.org/library/signal.html

  You want to trap SIGINT.

  HTH
  Philip

 Thanks to both of you. However, my question is also about whether I
 need to be doing i/o or some similar operation for my program to
 notice in any shape or form that Control-C has been pressed. In the
 past, I've written Python programs that go about their business
 ignoring Ctrl-C. Other programs respond to it immediately by exiting.
 I think the difference is that the latter programs are doing i/o. But
 I want to understand better what the secret is to responding to a
 ctrl-C in any shape or form.

 For example, does trapping SIGINT always work, regardless of what my
 process is doing?

 Thanks,
 Mike

Try some experiments. ;]
-- 
http://mail.python.org/mailman/listinfo/python-list


Catching control-C

2009-07-06 Thread Michael Mossey
What is required in a python program to make sure it catches a control-
c on the command-line? Do some i/o? The OS here is Linux.

Thanks,
Mike
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Catching control-C

2009-07-06 Thread Chris Rebert
On Mon, Jul 6, 2009 at 2:37 PM, Michael Mosseymichaelmos...@gmail.com wrote:
 What is required in a python program to make sure it catches a control-
 c on the command-line? Do some i/o? The OS here is Linux.

try:
#code that reads input
except KeyboardInterrupt:
#Ctrl-C was pressed

Cheers,
Chris
-- 
http://blog.rebertia.com
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Catching control-C

2009-07-06 Thread Philip Semanchuk


On Jul 6, 2009, at 5:37 PM, Michael Mossey wrote:

What is required in a python program to make sure it catches a  
control-

c on the command-line? Do some i/o? The OS here is Linux.


You can use a try/except to catch a KeyboardInterrupt exception, or  
you can trap it using the signal module:

http://docs.python.org/library/signal.html

You want to trap SIGINT.


HTH
Philip
--
http://mail.python.org/mailman/listinfo/python-list


Re: Catching control-C

2009-07-06 Thread Michael Mossey
On Jul 6, 2:47 pm, Philip Semanchuk phi...@semanchuk.com wrote:
 On Jul 6, 2009, at 5:37 PM, Michael Mossey wrote:

  What is required in a python program to make sure it catches a  
  control-
  c on the command-line? Do some i/o? The OS here is Linux.

 You can use a try/except to catch a KeyboardInterrupt exception, or  
 you can trap it using the signal 
 module:http://docs.python.org/library/signal.html

 You want to trap SIGINT.

 HTH
 Philip

Thanks to both of you. However, my question is also about whether I
need to be doing i/o or some similar operation for my program to
notice in any shape or form that Control-C has been pressed. In the
past, I've written Python programs that go about their business
ignoring Ctrl-C. Other programs respond to it immediately by exiting.
I think the difference is that the latter programs are doing i/o. But
I want to understand better what the secret is to responding to a
ctrl-C in any shape or form.

For example, does trapping SIGINT always work, regardless of what my
process is doing?

Thanks,
Mike
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Catching control-C

2009-07-06 Thread Philip Semanchuk


On Jul 6, 2009, at 6:02 PM, Michael Mossey wrote:


On Jul 6, 2:47 pm, Philip Semanchuk phi...@semanchuk.com wrote:

On Jul 6, 2009, at 5:37 PM, Michael Mossey wrote:


What is required in a python program to make sure it catches a
control-
c on the command-line? Do some i/o? The OS here is Linux.


You can use a try/except to catch a KeyboardInterrupt exception, or
you can trap it using the signal 
module:http://docs.python.org/library/signal.html

You want to trap SIGINT.

HTH
Philip


Thanks to both of you. However, my question is also about whether I
need to be doing i/o or some similar operation for my program to
notice in any shape or form that Control-C has been pressed. In the
past, I've written Python programs that go about their business
ignoring Ctrl-C. Other programs respond to it immediately by exiting.
I think the difference is that the latter programs are doing i/o. But
I want to understand better what the secret is to responding to a
ctrl-C in any shape or form.

For example, does trapping SIGINT always work, regardless of what my
process is doing?


Hi Mike,
Sorry, I don't know the Python internals well enough to answer your  
question.


Good luck
Philip

--
http://mail.python.org/mailman/listinfo/python-list


Re: Catching control-C

2009-07-06 Thread Ben Charrow
Michael Mossey wrote:
 On Jul 6, 2:47 pm, Philip Semanchuk phi...@semanchuk.com wrote:
 On Jul 6, 2009, at 5:37 PM, Michael Mossey wrote:
 
 What is required in a python program to make sure it catches a control- 
 c on the command-line? Do some i/o? The OS here is Linux.
 You can use a try/except to catch a KeyboardInterrupt exception, or you 
 can trap it using the signal 
 module:http://docs.python.org/library/signal.html
 
 You want to trap SIGINT.
 
 HTH Philip
 
 Thanks to both of you. However, my question is also about whether I need to 
 be doing i/o or some similar operation for my program to notice in any shape
  or form that Control-C has been pressed.

You don't need to be doing I/O in order to raise a KeyboardIneterrupt.  For
example, the following program should use up a lot of your CPU until you
hit Ctrl-C.

 while True:
... pass
...
^CTraceback (most recent call last):
  File stdin, line 1, in module
KeyboardInterrupt

 In the past, I've written Python programs that go about their business 
 ignoring Ctrl-C.

Can you be more specific?  Can you share the relevant sections of these
programs?  Were these programs multi-threaded?

 But I want to understand better what the secret is to responding to a 
 ctrl-C in any shape or form.

Strictly speaking, I don't think you can always respond to a Ctrl-C in any
shape or form.  Quoting from the signal module:

Although Python signal handlers are called asynchronously as far as the Python
user is concerned, they can only occur between the atomic instructions of the
Python interpreter. This means that signals arriving during long calculations
implemented purely in C (such as regular expression matches on large bodies of
text) may be delayed for an arbitrary amount of time.

HTH,
Ben

-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Catching control-C

2009-07-06 Thread Piet van Oostrum
 Philip Semanchuk phi...@semanchuk.com (PS) wrote:

PS On Jul 6, 2009, at 5:37 PM, Michael Mossey wrote:

 What is required in a python program to make sure it catches a  control-
 c on the command-line? Do some i/o? The OS here is Linux.

PS You can use a try/except to catch a KeyboardInterrupt exception, or  you
PS can trap it using the signal module:
PS http://docs.python.org/library/signal.html

PS You want to trap SIGINT.

And make sure threads don't mess up the signal handling.
-- 
Piet van Oostrum p...@cs.uu.nl
URL: http://pietvanoostrum.com [PGP 8DAE142BE17999C4]
Private email: p...@vanoostrum.org
-- 
http://mail.python.org/mailman/listinfo/python-list


Re: Catching control-C

2009-07-06 Thread Steven D'Aprano
On Mon, 06 Jul 2009 15:02:26 -0700, Michael Mossey wrote:

 On Jul 6, 2:47 pm, Philip Semanchuk phi...@semanchuk.com wrote:
 On Jul 6, 2009, at 5:37 PM, Michael Mossey wrote:

  What is required in a python program to make sure it catches a
  control-
  c on the command-line? Do some i/o? The OS here is Linux.

 You can use a try/except to catch a KeyboardInterrupt exception, or you
 can trap it using the signal
 module:http://docs.python.org/library/signal.html

 You want to trap SIGINT.

 HTH
 Philip
 
 Thanks to both of you. However, my question is also about whether I need
 to be doing i/o or some similar operation for my program to notice in
 any shape or form that Control-C has been pressed. In the past, I've
 written Python programs that go about their business ignoring Ctrl-C.

I bet that somewhere in your code you have something like:


for x in really_big_list:
try:
long_running_process(x)
except:
continue


If that's what you're doing, stop! The correct way is:


for x in really_big_list:
try:
long_running_process(x)
except Exception:
# Let KeyboardInterrupt and SystemExit through.
continue


or even:

for x in really_big_list:
try:
long_running_process(x)
except (KeyboardInterrupt, SystemExit):
print User requested exit... shutting down now
cleanup()
raise
except Exception:
continue



-- 
Steven
-- 
http://mail.python.org/mailman/listinfo/python-list