我知道python中的Keyboardinterupts存在一个带有多处理器任务的错误,但我也知道有一些解决方法。在这里我无法找到解决方案,因为线程是在cplex包内处理的,我不能(也不想)改变。
这是一个最小的例子:
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和待中断循环的脚本中?有什么想法吗?
答案 0 :(得分:0)
我想您可能在CPLEX Python API中发现了一个错误。我还不确定,但我认为默认信号处理程序没有在那里正确恢复(即,一旦你完成了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)
这是受this博客文章的启发,它可能实际上回答了你的大问题(如何在使用多处理时处理KeyboardInterrupt)。