解决cplex模型后,Keyboardinterupt不起作用

时间:2016-08-31 11:32:28

标签: python multithreading cplex keyboardinterrupt

我知道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和待中断循环的脚本中?有什么想法吗?

1 个答案:

答案 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)。