Unresponsive program still running

Python

  • (2 Pages)
  • +
  • 1
  • 2

15 Replies - 12895 Views - Last Post: 02 October 2010 - 06:43 PM Rate Topic: -----

#1 Eric115  Icon User is offline

  • coderさん
  • member icon

Reputation: 63
  • View blog
  • Posts: 696
  • Joined: 19-January 09

Unresponsive program still running

Posted 30 September 2010 - 11:07 PM

Hi all,
I wrote a simple program to backup my USB using the shutil module for the copying. It also can delete old backups. The problem I am getting is when the program starts copying the files from the USB to the destination, the program is registered as unresponsive, when the program is actually still responsive! I have tried my program on windows 7 and windows XP and the same thing happens. I also use the shutil.rmtree to remove old backups, and when this happens once again the program is registered as unresponsive even though it is still working.
This isn't a major problem, but if I want to distribute the program no doubt some one is going to have trouble because of it. The commands used when it goes unresponsive are;
shutil.copytree(Dir, f+"\Backup"+Snumb)
#and
for k in range(0, CleanNum):
    print "loop running"
    SCleanNum = str(CleanNum)
    print "SCleanNum made"
    shutil.rmtree(f+"\Backup"+SCleanNum)
    print "shutil.rmtree(f+'\Backup'+SCleanNum)"
    CleanNum = CleanNum - 1                                           


Everything in the program works, it's just when windows calls it unresponsive.
Any help would be greatly appreciated. Thanks in advance

Is This A Good Question/Topic? 0
  • +

Replies To: Unresponsive program still running

#2 Guest_c.user*


Reputation:

Re: Unresponsive program still running

Posted 01 October 2010 - 04:23 AM

    print "SCleanNum made"
    print (f + "\Backup" + SCleanNum), CleanNum


Was This Post Helpful? 0

#3 Motoma  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 452
  • View blog
  • Posts: 796
  • Joined: 08-June 10

Re: Unresponsive program still running

Posted 01 October 2010 - 05:22 AM

The cause of your issue is that Python is single-threaded by default. If the program is working, than it's not doing anything else--not accepting IO from the user, the OS, or anything unrelated to the single task it is performing.

A robust solution to your problem would be to separate your worker code and status code with threads. You would essentially spawn a thread for your worker code, and have it write all output to a Queue.Queue. Your main thread would be a short loop pop()ing the Queue, printing any message, and sleeping for half a second. This will guarantee that your OS won't register the program as unresponsive, because the main thread will be able to respond to any OS IO every half-second.

I can give you some sample code for this, just let me know if you want it.

Cheers,
Motoma
Was This Post Helpful? 1
  • +
  • -

#4 Eric115  Icon User is offline

  • coderさん
  • member icon

Reputation: 63
  • View blog
  • Posts: 696
  • Joined: 19-January 09

Re: Unresponsive program still running

Posted 01 October 2010 - 05:56 AM

Thank you for your reply. I sort of get what you mean but some sample code would be greatly appreciated if you could give it to me. I haven't used threads before but I sort of get what you mean. Would I have to launch a second program so I could do this or can you handle two threads in the main program?
Thanks again for your help.

Quote

print "SCleanNum made"
print (f + "\Backup" + SCleanNum), CleanNum

c.user, I have no idea what you mean?? :?:

This post has been edited by Eric115: 01 October 2010 - 06:04 AM

Was This Post Helpful? 0
  • +
  • -

#5 Motoma  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 452
  • View blog
  • Posts: 796
  • Joined: 08-June 10

Re: Unresponsive program still running

Posted 01 October 2010 - 06:17 AM

You will be able to handle both threads in your main code. This example is written for Python 2.x; it changes a little in 3.x because the thread module has been deprecated and renamed to _thread.

#! /usr/bin/env python

import Queue
import thread
import time

messageq = Queue.Queue()
loop_running = True

def worker_function(count, name):
    # just an example of something that will hang when run as a single thread:
    for i in range(count):
        time.sleep(30)
        messageq.put('%s finished loop %i.' % (name, i))

    # let the main thread know we're done
    loop_running = False

def main():
    # an example of passing arguments to threads
    thread.start_new_thread(worker_function, (10, 'This program'))

    # only do this while the worker thread is running
    while loop_running:
        try:
            # don't block or the program will seem unresponsive!
            message = messageq.get(False)
            print message

        except Queue.Empty:
            # we don't care that the worker hasn't said anything yet
            pass

        # check on the worker 10 times per second
        time.sleep(0.1)

if __name__ == '__main__':
    main()



When you run the code, you'll see that the application window remains perfectly responsive, while the worker process performs tasks that would normally cause it to hang.

If you have any questions, please don't hesitate to ask.

This post has been edited by Motoma: 01 October 2010 - 06:21 AM

Was This Post Helpful? 1
  • +
  • -

#6 Motoma  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 452
  • View blog
  • Posts: 796
  • Joined: 08-June 10

Re: Unresponsive program still running

Posted 01 October 2010 - 06:27 AM

There are some pieces there that aren't entirely necessary. I do a lot of work with multi-threaded programs, so I like to build in things like thread-safe message passing (the Queue.Queue) and loop status variable.

This post has been edited by Motoma: 01 October 2010 - 06:29 AM

Was This Post Helpful? 0
  • +
  • -

#7 Eric115  Icon User is offline

  • coderさん
  • member icon

Reputation: 63
  • View blog
  • Posts: 696
  • Joined: 19-January 09

Re: Unresponsive program still running

Posted 01 October 2010 - 05:43 PM

Thank you so much for your help! I'll add the thread in now and see if it helps.

This post has been edited by Eric115: 01 October 2010 - 05:49 PM

Was This Post Helpful? 0
  • +
  • -

#8 Eric115  Icon User is offline

  • coderさん
  • member icon

Reputation: 63
  • View blog
  • Posts: 696
  • Joined: 19-January 09

Re: Unresponsive program still running

Posted 01 October 2010 - 06:51 PM

Ok, so I tried to use your thread code to run the shutil.copytree command. But there is a problem. I put your code for the main() into a function I had already. Everything works fine until I call the thread.start_new_thread(backupProcess, (count)). I don't understand what is wrong here. When I take out all of the try and except statements (for error catching) it tells me that backupProcess is not defined, but it definitely is (I copied the name into the thread call). I can post my code here if you need it, just let me know. Thanks

EDIT:
I just tried something else, I put the shutil function into your code. I put it under the print message and it worked! But it still won't work in my code? Just thought I would mention this in case it helps.

This post has been edited by Eric115: 01 October 2010 - 07:12 PM

Was This Post Helpful? 0
  • +
  • -

#9 Guest_c.user*


Reputation:

Re: Unresponsive program still running

Posted 01 October 2010 - 07:46 PM

View PostEric115, on 01 October 2010 - 10:56 PM, said:

Quote

print "SCleanNum made"
print (f + "\Backup" + SCleanNum), CleanNum

c.user, I have no idea what you mean?? :?:


How did you know that your loop is working right ?

This post has been edited by c.user: 01 October 2010 - 07:46 PM

Was This Post Helpful? 0

#10 Eric115  Icon User is offline

  • coderさん
  • member icon

Reputation: 63
  • View blog
  • Posts: 696
  • Joined: 19-January 09

Re: Unresponsive program still running

Posted 01 October 2010 - 08:37 PM

Quote

How did you know that your loop is working right ?

Because after I run it, all of the files are deleted. With the other one, when I run it, even though it says it's unresponsive, If I mouse over the file it is copying to, the size of the file is continuing to increase and as soon as the copying is finished the program returns to normal. Also the print statements print every time the loop runs through.

This post has been edited by Eric115: 01 October 2010 - 08:38 PM

Was This Post Helpful? 1
  • +
  • -

#11 Motoma  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 452
  • View blog
  • Posts: 796
  • Joined: 08-June 10

Re: Unresponsive program still running

Posted 02 October 2010 - 05:06 AM

View PostEric115, on 01 October 2010 - 07:51 PM, said:

thread.start_new_thread(backupProcess, (count)). I don't understand what is wrong here. When I take out all of the try and except statements (for error catching) it tells me that backupProcess is not defined, but it definitely is (I copied the name into the thread call). I can post my code here if you need it, just let me know.


Let's take a look at your code and see if we can find where the problem is.
Was This Post Helpful? 0
  • +
  • -

#12 Eric115  Icon User is offline

  • coderさん
  • member icon

Reputation: 63
  • View blog
  • Posts: 696
  • Joined: 19-January 09

Re: Unresponsive program still running

Posted 02 October 2010 - 05:14 AM

Alright, here is my code with your code added in:
I'll just post the bit that applies to this, the whole thing is well over 300 lines with the GUI.
    def worker_function(count):
        # just an example of something that will hang when run as a single thread:
        for i in range(count):
            time.sleep(30)
            messageq.put('finished loop %i.' % (i))

    # let the main thread know we're done
        loop_running = False
        
    def backup(self, event):
        #if self.compress == True:
        if 1 == 2:
            #self.backupCompress(event)
            pass
        else:
        
            try:    
                fOpen = open('Backup.pth', 'r')
                f = fOpen.read()
                fOpen.close()
                checkFile = os.path.exists(f)
                if checkFile == True:
                    self.components.stSynching.visible = 1
                    
                    dialog.alertDialog(self, "Syncher will now synch."\
                    "\n Windows may register this program as unresponsive while it is"\
                    " synching. If this happens do not exit the program as it will"\
                    " still finish the synch process.", "Syncher")
                    Dir = os.path.curdir
                    print Dir
                    try:
                        number = FileNumber.NewNumb(f, 'Backup')
                        if number == "File does not exist!":
                            dialog.alertDialog(self, "Can not find files!", "Syncher")
                            self.components.stSynching.visible = 0 
                              
                        else:
                            Snumb = str(number)
                            print Snumb
                            #put thread here
                            count = 1
                            messageq = Queue.Queue()
                            print 'Queue.Queue()'
                            loop_running = True
                            print 'Loop_running = True'
                            thread.start_new_thread(worker_function, (count))
                            print 'Called thread'

                            # only do this while the worker thread is running
                            while loop_running:
                                try:
                                    # don't block or the program will seem unresponsive!
                                    message = messageq.get(False)
                                    print message
                                    shutil.copytree(Dir, f+"\Backup"+Snumb)

                                except Queue.Empty:
                                    # we don't care that the worker hasn't said anything yet
                                    pass

                                # check on the worker 10 times per second
                                time.sleep(0.1)
                            #shutil.copytree(Dir, f+"\Backup"+Snumb)
                            dialog.alertDialog(self, "Syncher has finished backing up"\
                            " your USB.", "Syncher")
                            done = True
                            self.components.stSynching.visible = 0 
                            
                    except:
                        dialog.messageDialog(self, "An Error has occured while Synching!",
                        "Syncher", wx.ICON_ERROR | wx.OK)
                        self.components.stSynching.visible = 0
                              
                elif checkFile == False:
                    dialog.messageDialog(self, "Selected directory does not exist!",
                    "Syncher", wx.ICON_ERROR | wx.OK)
                    self.components.stSynching.visible = 0
                      
            except:
                reSynch = dialog.messageDialog(self, "An error has"\
                " occured while trying to backup"\
                " your files! Please make sure you have selected a directory to back up to.", "Syncher",
                wx.ICON_ERROR)
                self.components.stSynching.visible = 0



Sorry it's so long. Also, I left your comments in the code so I had some idea of what was what. Thanks for your help. If you need any more code or anything just let me know!
p.s. In case you need to know, the FileNumber module is just something to give me a number for a folder I haven't used yet (e.g. Folder1, Folder2, it returns 3).
Was This Post Helpful? 0
  • +
  • -

#13 Motoma  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 452
  • View blog
  • Posts: 796
  • Joined: 08-June 10

Re: Unresponsive program still running

Posted 02 October 2010 - 05:28 AM

I think you've misinterpreted the intent of my code (it's confusing, I know). The worker_function thread is going to be where you do all of the work; in your case, all of the shutil calls should be made there.

Rather than printing directly, worker_function should then put status messages on the message queue (messageq).

The main thread's sole job is to monitor the message queue and print messages as they are received.

I am unable to run the code you've posted. Could you post the error message here?
Was This Post Helpful? 0
  • +
  • -

#14 Eric115  Icon User is offline

  • coderさん
  • member icon

Reputation: 63
  • View blog
  • Posts: 696
  • Joined: 19-January 09

Re: Unresponsive program still running

Posted 02 October 2010 - 05:40 AM

The code isn't complete, only the two functions involving the threads (and the problem). The only problem I seem to be having is when I call the thread using the thread.start_new_thread. This is the error message I get:
thread.start_new_thread(worker_function, (count))
NameError: global name 'worker_function' is not defined

I also tried re-naming the worker function and I still had the same error. I am at a loss to what it means because the I have defined the worker_function, so why can't it see it?
Thanks for your help.
Was This Post Helpful? 0
  • +
  • -

#15 Motoma  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 452
  • View blog
  • Posts: 796
  • Joined: 08-June 10

Re: Unresponsive program still running

Posted 02 October 2010 - 06:50 AM

View PostEric115, on 02 October 2010 - 06:40 AM, said:

The code isn't complete, only the two functions involving the threads (and the problem). The only problem I seem to be having is when I call the thread using the thread.start_new_thread. This is the error message I get:
thread.start_new_thread(worker_function, (count))
NameError: global name 'worker_function' is not defined

I also tried re-naming the worker function and I still had the same error. I am at a loss to what it means because the I have defined the worker_function, so why can't it see it?
Thanks for your help.


Does this happen to be part of a class? In that case you would need to call thread.start_new_thread(self.worker_function, (count))

If you call the function in a single-threaded manner in the same location, do you get the error?

worker_function(count)
thread.start_new_thread(worker_function, (count))



The most likely cause of this is a simple scoping issue.
Was This Post Helpful? 0
  • +
  • -

  • (2 Pages)
  • +
  • 1
  • 2