我知道在多处理器任务的python中有一个键盘中断的错误,但我也知道有一些解决方法。这里我无法找到解决方案,因为线程是在复杂包内处理的,我不能(也不想)改变。
下面是一个简单的例子:
def test_interupt():
"""loops until Ctrl-C is pressed"""
i = 0
try:
while True:
i+=1
except KeyboardInterrupt:
print 'interrupted at i='+str(i)
def solve_dummy_cplex_problem():
"""solves the dummy optimization problem max{x|x<42}"""
import cplex
c = cplex.Cplex()
c.objective.set_sense(c.objective.sense.maximize)
c.variables.add(names=['x'], types=[c.variables.type.continuous])
c.set_problem_type(c.problem_type.LP)
c.linear_constraints.add(rhs=[42], senses='L', names=['cons1'])
c.objective.set_linear( [(0,1)] )
c.linear_constraints.set_coefficients([(0,0,1)])
c.solve()
print c.solution.get_values(0)
test_interupt()
solve_dummy_cplex_problem()
test_interupt()
当我运行这段代码时,我可以中断第一个循环,但不能中断第二个循环。一旦调用了cplex(并且可能已经启动了多线程作业,但是当我第二次按ctrl-C时,它们应该已经完成了),我在屏幕上打印了'^C',但是我不能中断第二个循环。
但是,请注意,当我在提示符中输入 时,问题不会出现。In [1]: test_interupt()
^Cinterrupted at i=213655938
In [2]: solve_dummy_cplex_problem()
Freeing MIP data.
Tried aggregator 1 time.
LP Presolve eliminated 1 rows and 1 columns.
All rows and columns eliminated.
Presolve time = 0.00 sec. (0.00 ticks)
42.0
In [3]: test_interupt()
^Cinterrupted at i=35459170
那么,我如何获得与提示符相同的行为,但在调用复杂和被中断循环的脚本中?有什么想法吗?
我想你可能在CPLEX Python API中发现了一个bug。我还不确定,但我认为默认的信号处理程序没有被正确地恢复(即,一旦你用CPLEX完成,它就会损坏)。
对于你的特定问题,这是一个(丑陋的?)变通方法:
import signal
def test_interupt(handler):
"""loops until Ctrl-C is pressed"""
signal.signal(signal.SIGINT, handler)
i = 0
try:
while True:
i+=1
except KeyboardInterrupt:
print 'interrupted at i='+str(i)
def solve_dummy_cplex_problem():
"""solves the dummy optimization problem max{x|x<42}"""
import cplex
c = cplex.Cplex()
c.objective.set_sense(c.objective.sense.maximize)
c.variables.add(names=['x'], types=[c.variables.type.continuous])
c.set_problem_type(c.problem_type.LP)
c.linear_constraints.add(rhs=[42], senses='L', names=['cons1'])
c.objective.set_linear( [(0,1)] )
c.linear_constraints.set_coefficients([(0,0,1)])
c.solve()
print c.solution.get_values(0)
defaulthandler = signal.getsignal(signal.SIGINT)
test_interupt(defaulthandler)
solve_dummy_cplex_problem()
test_interupt(defaulthandler)
这是受到这篇博客文章的启发,这篇文章实际上可能会回答你更大的问题(如何在使用多处理时处理KeyboardInterrupt)。