0

I am trying to gently terminate a running thread in Python by calling stopThread on the object worker running in another thread.

However doing so is giving me the error:

AttributeError: 'Thread' object has no attribute 'stopThread'

How can we fix this issue?

import threading
import time

class Worker(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)
        self.stopRequest = threading.Event()

    def doSomething(self):
        while True:
            if not self.stopRequest.isSet():
                print 'Doing something'
                time.sleep(5)

    def stopThread(self):
        self.stopRequest.set()


def startWorker():
    worker = Worker()
    worker.doSomething()


# Start thread
t = threading.Thread(target=startWorker)
t.start()

# Stop thread
t.stopThread()
Nyxynyx
  • 61,411
  • 155
  • 482
  • 830
  • Helpful thread termination discussion: http://stackoverflow.com/questions/323972/is-there-any-way-to-kill-a-thread-in-python – DYZ Mar 01 '17 at 23:20
  • You're not creating an instance of your `Worker` subclass as you probably think you are. See [**_How to start and stop thread?_**](http://stackoverflow.com/questions/15729498/how-to-start-and-stop-thread) for examples. – martineau Mar 01 '17 at 23:57

1 Answers1

0

You have the error:

AttributeError: 'Thread' object has no attribute 'stopThread'
                 ^^^^^^^^^^^^^^

because

t = threading.Thread(target=startWorker)

..and not a Worker object as you intend.

May be say: t = Worker(target=startWorker) ? Of course, you'd have to take keyword arguments as additional parameters and send them to your super class Thread.


Or, did you want you say: worker.stopThread() within startWorker() instead of t.stopThread() outside?

martineau
  • 119,623
  • 25
  • 170
  • 301
UltraInstinct
  • 43,308
  • 12
  • 81
  • 104
  • I updated the code in the question to better reflect what I'm trying to do. I'm new to threading in Python. Basically trying to create an object `Worker` where all its code will run in a different thread, run the `doSomething` method then terminate the thread. – Nyxynyx Mar 01 '17 at 23:27
  • My code was trying to get the function `startWorker` to run in a new thread – Nyxynyx Mar 01 '17 at 23:28
  • I read your code. You're actually confusing various things. 1) Is `Worker` class supposed to behave like a thread? Or is it supposed to be something non-thread-like and do some work? If it's the latter, inheriting the `Worker` class from `Thread` makes no sense. If it's the prior, you should say: `t = Worker(..)` as in the first part of my answer. 2) You are setting the `threading.Event` but never using it. You should have a loop or something that checks this object. This makes me think may be intend to make Worker thread-like. Look at this answer: http://stackoverflow.com/a/27261365/227884 – UltraInstinct Mar 01 '17 at 23:34
  • Sorry for the confusion. Updated code again with loop and the use of `threading.Event()`, What I am trying to achieve here is to run `Worker.doSomething()` asynchronously in a separate thread so the main thread can still do other things – Nyxynyx Mar 01 '17 at 23:46
  • Tried `t = Worker(target=startWorker)` but it gave an error `TypeError: __init__() got an unexpected keyword argument 'target'`. – Nyxynyx Mar 01 '17 at 23:47
  • @Nyxynyx: I'd suggest you read up on basics of how to inherit classes and pass the super class `__init__(..)` arguments. You should take `target` argument in your worker class, and then pass it like: `threading.Thread.__init__(self, target=target)`. But before anything else, read the answer I linked in the previous comment. – UltraInstinct Mar 02 '17 at 00:45