Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is the main thread of my multithreaded application unresponsive to Ctrl+C?

Tags:

python

windows

I have written a multithreaded application to watch and respond to changes in given list of files. I have a Watch class which gets the file size and sets it to size variable upon first call. Then, after a few seconds it again gets the size of the file and compares it with with the previous size and, if changed, sets size to the current size of the file. Furthermore there is a WatchWorker class which is a subclass of threading.Thread. The WatchWorker which makes use of Watch class to 'watch ' a given file.

Now here is the real problem : The code I have written is working and notifies the user when a change is detected. But there is no response when I try to quit from the application using Ctrl+C. I'm on Windows.

Code:

import time
import threading
import os

class Watch(object):
    def __init__(self, path, time=5):
        self.path = path
        self.time = time
        self.size = os.stat(path).st_size



    def loop(self):
        while True:
            time.sleep(self.time)
            size = os.stat(self.path).st_size
            if size != self.size:
                self.size = size
                print "Change detected in file {}".format(self.path)



class Watch_Worker(threading.Thread):
    def __init__(self, path, *args, **kwargs):
        super(Watch_Worker, self).__init__(*args, **kwargs)
        self.path = path


    def run(self):
        super(Watch_Worker, self).run()
        Watch(self.path).loop()

def main(*args):
    for i in args:
        thrd = Watch_Worker(path=i)
        thrd.start()
        print 'Watching ' + i
        print "From main thread"



if __name__ == '__main__':
    main('blah.js', 'cs.c', 'ab.rb')

Edit

Modified code to compare the values produced os.stat('somefile.ext').st_size).

like image 584
OMG coder Avatar asked Jan 01 '16 16:01

OMG coder


1 Answers

I solved the problem of the main thread being prevented from exiting by setting self.daemon = True. The main thread does not wait for the threads to exit. This is solved by adding a infinite while loop withtime.sleep(5) to the end of main function. Here is the code:

class Watch_Worker(threading.Thread):
        def __init__(self, path, time=2,  *args, **kwargs):
            super(Watch_Worker, self).__init__(*args, **kwargs)
            self.path = path
            self.time = time
            self.size = os.stat(path).st_size
            self.daemon = True


        def run(self):
            super(Watch_Worker, self).run()
            while True:
                time.sleep(self.time)
                size = os.stat(self.path).st_size
                if size != self.size:
                    self.size = size
                    print "Change detected in file {}".format(self.path)

    def main(*args):
        for i in args:
            thrd = Watch_Worker(path=i)
            thrd.start()
            print 'Watching ' + i
         while True:
             time.sleep(5)


    if __name__ == '__main__':
        main('blah.js', 'cs.c', 'ab.rb')
like image 194
OMG coder Avatar answered Oct 28 '22 00:10

OMG coder