Originally posted by: WPettersson
I've developing a somewhat-interactive app doing some optimisation using CPLEX. It has a Qt GUI using PyQt5, and calls CPLEX to optimise a problem. I run CPLEX in a worker thread (specifically, QThread), and communicate between threads to show the user how the optimisation is going, and let the user terminate the process. This all works perfectly fine in Linux.
I'm now trying to port to Windows, and CPLEX crashes on me. Specifically I get
C:\Users\User\Documents>python mipex4.py era_allocator/python.lp
Exception in thread Thread-1:
Traceback (most recent call last):
File "C:\Users\User\AppData\Local\Programs\Python\Python35\lib\threading.py", line 914, in _bootstrap_inner
self.run()
File "mipex4.py", line 54, in run
c.solve()
File "C:\Users\User\AppData\Local\Programs\Python\Python35\lib\site-packages\cplex\__init__.py", line 1078, in solve
_proc.mipopt(self._env._e, self._lp)
File "C:\Users\User\AppData\Local\Programs\Python\Python35\lib\site-packages\cplex\_internal\_procedural.py", line 540, in mipopt
with SigIntHandler():
File "C:\Users\User\AppData\Local\Programs\Python\Python35\lib\site-packages\cplex\_internal\_procedural.py", line 168, in __init__
signal.signal(signal.SIGINT, sigint_handler)
File "C:\Users\User\AppData\Local\Programs\Python\Python35\lib\signal.py", line 47, in signal
handler = _signal.signal(_enum_to_int(signalnum), _enum_to_int(handler))
ValueError: signal only works in main thread
This error happens, of course, because I'm not running CPLEX in the main thread (that's where my GUI is).
I've uploaded a sample script which demonstrates the problem to https://gist.github.com/WPettersson/d8436502f8e81a918867add2c75a503e This runs fine under Linux, but under Windows will crash as above when given a valid LP file as a parameter.
This is trivial to avoid by shoving
# Do nothing if we aren't the main thread
if threading.main_thread() != threading.current_thread():
return
into SigIntHandler() in _procedural.py, and with this change my test program runs fine. I do understand that this means CTRL+C won't interrupt the program, so maybe you want to take a slightly different approach, but I at least wanted to point out what a fix could look like. Alternatives could include: add warning to this fix about running in background, or even requiring the user set some "run_in_background" flag before enabling it.
#CPLEXOptimizers#DecisionOptimization