解决复杂模型后,键盘中断不工作



我知道在多处理器任务的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)。

最新更新