0

Python GUI with Tk that a user adds servers to and it displays port and resource information about the server. Each server line is running in its own thread and loops with a myQueue.put(executor.submit(lambda: <function here>)). I can load up 15 servers and then close the window. Sometimes the python.exe closes and the IDE shows the application end with exit code 0. Sometimes I close the window and the IDE and task manager show that the program is still running. After a while the pycharm console prints "main thread is not in main loop" and nothing else happens after that. I thought using a queue with the threads would keep this from happening but something is going wrong.

Workflow for the below code: user adds server info in a popup window> that is run through creation function> information is passed off to threadmaker function that watches an indicator and reruns the SSH session to query info when the previous query finishes.

main = Tk()
myQueue = queue.Queue()
executor = concurrent.futures.ThreadPoolExecutor(max_workers=16)

def creation(server, nickname, user, passw):

    #Create label for server, nickname, user, password here and place them on the main window

    myQueue.put(executor.submit(lambda: threadmaker(server, nickname, user, passw)))

def threadmaker(server, nickname,  user, passw):
    # this function loops until indicator is 0 and then runs refresh function
    global workinglist
    if 'normal' == main.state():
        if workinglist[server + "counter"] == "1":
            time.sleep(3)
            myQueue.put(executor.submit(threadmaker(server, nickname, user, passw)))
        if workinglist[server + "counter"] == "0":
            myQueue.put(executor.submit(refresh(server, nickname, user, passw)))
            time.sleep(3)
            myQueue.put(executor.submit(threadmaker(server, nickname, user, passw)))

    if 'normal' != main.state():
        print(main.state())
        pass

def refresh(server, nickname, user, passw):
    global workinglist
    workinglist[server + "counter"] = "1"
    if 'normal' == main.state():
                if 'normal' == main.state():
                    try:
                        ssh = paramiko.SSHClient()
                        ssh.load_system_host_keys()
                        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
                        ssh.connect(str(server), username=str(user), password=str(passw), timeout=10, allow_agent=False, look_for_keys=False)
                        stdin, stdout, stderr = ssh.exec_command("DF -H")
                        type(stdin)
                        test2 = stdout.readlines()
                        stdin.flush()
                        stdin.close()
                        ssh.close()
                         #<< do soething with the test2 value>>

                    except Exception as E:
                        print(E)

                if 'normal' == main.state():
                    try:
                        #<< another ssh query >>
                    except Exception as E:
                        pass
    workinglist[server + "counter"] = "0"

main.mainloop()

Am I handling the threads or the queue incorrectly?

I've added print(threading.currentThread().getName(), 'Starting') to the beginning of the refresh function and the running thread number never gets over the number of servers added + 1 for the main thread. So if Im handling all the threads with my threadpool what is hanging up? I assume something with the ssh attempt.

sidnical
  • 421
  • 1
  • 6
  • 23
  • Add exit() at the end of thread_loop and run, to check if python.exe is the threads or the main program – Radagast Nov 11 '16 at 18:21
  • @Radagast I added exit() at the end of the refresh function ( I assume this is where you meant to put it ) and im still able to cause the hangup. Something else I noticed- after posting to SO I left the machine for ~1 hour and when I came back the program seemed to exit every time without an issue. Relaunching 4 or 5 times finally replicated the issue but I thought it was odd. I only see the "main thread is not in main loop" message when the hangup happens. – sidnical Nov 11 '16 at 19:27
  • Now the hangup seems to happen every time I run from the IDE. This makes the issue seem more random or like it only happens if its closed during a specific process thats running. I'll update the question with this. – sidnical Nov 11 '16 at 19:38
  • I figured out what is happen, see this answer http://stackoverflow.com/questions/10556479/running-a-tkinter-form-in-a-separate-thread/10556698#10556698 – Radagast Nov 11 '16 at 19:51
  • @Radagast They mention the program gui freezing in that thread. Just to clarify, my gui does not freeze when im doing anything. Its just on the close. That being said I see what they are saying about putting the results in a queue and letting the main thread watch that queue for updates. How would I put changes to a Label into the queue and let the main thread apply that change? if I run a loop in the main thread that watches a queue it will cause the gui to freeze. To avoid that I have to run the loop in a new thread which leads back to the same problem. – sidnical Nov 11 '16 at 20:04

0 Answers0