how to terminate a thread which calls the webbrowser in python - python

I am developing an app which is linux based but right now I am facing as I have to call the webbrowser to do the further task but the problem is the program gets stuck and does not terminate. I have tried to terminate it using thread but it doesn't receive the interrupt and the thread runs infinitely ,below is the basic version of the code I was trying.Hope you got my problem ,
import time
import threading
import webbrowser
class CountdownTask:
def __init__(self):
self._running = True
def terminate(self):
self._running = False
def run(self):
url='http://www.google.com'
webbrowser.open(url,new=1)
c = CountdownTask()
t = threading.Thread(target=c.run)
t.start()
time.sleep(1)
c.terminate() # Signal termination
t.join() # Wait for actual termination (if needed)

import time
import threading
import webbrowser
class CountdownTask(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self._running = True
def terminate(self):
self._running = False
def run(self):
url='http://www.google.com'
webbrowser.open(url,new=1)
t = CountdownTask()
t.start()
time.sleep(1)
t.terminate() # Signal termination
t.join() # Wait for actual termination (if needed)

Related

What happens if the function of a python thread is completed?

I am using python thread while I found no method to stop it.
Here is how I use the thread:
class MyThread(Thread):
def __init__(self, func, args=()):
Thread.__init__(self)
self.__return_value = None
self.func = func
self.args = args
self.func_name = func.__name__
def run(self):
self.__return_value = self.func(*self.args)
Considering there is no explicit way to stop it, I try to ignore it when it finishes the function to execute.
Will a zombie thread left if I do nothing when it finishes?
No - the thread pack up after itself and shuts down cleanly.
It is how things in Python try to work, after all.
import threading
import time
def worker():
time.sleep(1)
def main():
print (threading.active_count())
t = threading.Thread(target=worker)
t.start()
print(threading.active_count())
time.sleep(2)
print(threading.active_count())
return t
main()
t = main()
t.is_alive()
Running this snippet in ipython (an interactive prompt which uses some threads for its own purposes) will print
4
5
4
False

how can stop only thread but program should keep running in python

import time
import threading
class Check(threading.Thread):
def __init__(self):
self.stopped = False
threading.Thread.__init__(self)
def run(self):
i = 0
while not self.stopped:
time.sleep(1)
i = i + 1
print(i)
if(i==5):
self.stopped = True
inst = Check()
inst.start()
You have to set up your own mechanism for stopping a thread--Python doesn't have a built-in way to do it. This is actually a common problem among many languages, not just Python.
import time
import threading
class Check(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
# An event can be useful here, though a simple boolean works too since
# assignment is atomic in Python.
self.stop_event = threading.Event()
def run(self):
i = 0
while not self.stop_event.is_set():
time.sleep(1)
i = i + 1
print(i)
if(i==5):
self.stopped = True
def stop(self):
# Tell the thread to stop...
self.stop_event.set()
# Wait for the thread to stop
self.join()
inst = Check()
inst.start()
# Do stuff...
time.sleep(1)
inst.stop()
# Thread has stopped, but the main thread is still running...
print("I'm still here!")
Here I use an event to signal whether or not the thread should stop. We add a stop method to signal the event and then wait for the thread to finish processing before continuing. This is very simplistic, but hopefully it gives you the idea of the kind of strategy you can take. It gets much more complicated if you want to handle error conditions like being informed if an error occurred in the run() method or if the body of the run() method is taking too long, etc.

time.sleep blocks while loop in thread

When I run a While True loop in thread and use time.sleep() function the loop stops looping.
I am using this code:
import threading
from time import sleep
class drive_worker(threading.Thread):
def __init__(self):
super(drive_worker, self).__init__()
self.daemon = True
self.start()
def run(self):
while True:
print('loop')
#some code
time.sleep(0.5)
To start the thread I am using this code:
thread = drive_worker()
The loop stops because you flagged the thread as daemon.
The program terminates when there are only daemon threads left running.
self.daemon = True # remove this statement and the code should work as expected
Or make the main thread wait for the the daemon thread to finish
dthread = drive_worker()
# no call to start method since your constructor does that
dthread.join() #now the main thread waits for the new thread to finish
You imported sleep as
from time import sleep
so you have to call sleep in run() as sleep(0.5) or you have to change import as
import time
which I do not recommend.

How to stop a dbus gobject loop

I try to stop a gobject.MainLoop() after a few seconds.
I don't know if it's possible to set a timeout to this kind of loop, it would be perfect but I have not found that.
So, I tried to workaround this with threading but unfortunately, the main loop block others threads.
Here my code (I'm working with python 2.7):
import MediaCenter_dbusConfig
import dbus
import gobject
from dbus.mainloop.glib import DBusGMainLoop
from time import sleep
from threading import Thread
mainloop=0
class Timeout(Thread):
global mainloop
def __init__(self):
Thread.__init__(self)
def run(self):
global mainloop
i = 0
while i < 30:
sleep(1)
i += 1
mainloop.quit()
class Loop(Thread):
global mainloop
def __init__(self):
Thread.__init__(self)
def run(self):
global mainloop
sleep(5)
mainloop.run()
def catchall_detectedDevicePopUp_from_willShowPopup_signals_handler(popup_string):
global mainloop
if(popup_string == "DetectedDevicePopUp.qml") :
print(popup_string)
mainloop.quit()
def detectedDevicePopUp_detector() :
global mainloop
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
bus=MediaCenter_dbusConfig.init() # basicly do a dbus.bus.BusConnection()
bus.add_signal_receiver(catchall_detectedDevicePopUp_from_willShowPopup_signals_handler, dbus_interface = "com.orange.mediacenter.apimanager", signal_name = "willShowPopup")
mainloop = gobject.MainLoop()
thread1 = Timeout()
thread2 = Loop()
thread1.start()
thread2.start()
thread1.join()
thread2.join()
Here I call detectedDevicePopUp_detector(). I'm waiting for a signal named willShowPopup. If I received a signal, I want to stop the loop and continue my program, and after 30s, if I have not received any signal, I want the same thing (stop the loop and continue my program) but here it doesn't work, my Timeout thread is blocked by my Loop thread.
Clarification: I can not edit the signals sent (I test an application).
Any ideas ?
As I understood the question, threading is not really wanted. Below is an example that uses gobject.timeout_add to add a maximum time that the mainloop will run if there is no signal to stop it:
import gobject
import dbus
import dbus.service
from dbus.mainloop.glib import DBusGMainLoop
DBusGMainLoop(set_as_default=True)
OPATH = "/com/example/StopLoop"
IFACE = "com.example.StopLoop"
BUS_NAME = "com.example.StopLoop"
TIMEOUT = 30 * 1000
class Example(dbus.service.Object):
def __init__(self, loop):
self.loop = loop
bus = dbus.SessionBus()
bus.request_name(BUS_NAME)
bus_name = dbus.service.BusName(BUS_NAME, bus=bus)
dbus.service.Object.__init__(self, bus_name, OPATH)
# Add a timeout for how long to run mainloop
# if no signal is received
self.setup_timeout(TIMEOUT)
# Listen to the "Stop" signal
self.listen_for_signal(bus)
def setup_timeout(self, timeout):
gobject.timeout_add(timeout, self.handler)
def listen_for_signal(self, bus):
bus.add_signal_receiver(self.handler, "Stop")
def handler(self):
# This handler is used for both timeout and signal
self.loop.quit()
if __name__ == "__main__":
loop = gobject.MainLoop()
a = Example(loop)
loop.run()
print "Exited mainloop, continuing program..."
If the Stop signal is received e.g. by doing:
dbus-send --session --type=signal --dest=com.example.StopLoop /com/example/StopLoop com.example.StopLoop.Stop
The mainloop will exit and the code will continue from where loop.run() was called.
If no signal is received the mainloop will be stopped by the timeout (30 seconds in this case) and continue from where loop.run() was called.

Non-blocking class in python (detached Thread)

I'm trying to create a kind of non-blocking class in python, but I'm not sure how.
I'd like a class to be a thread itself, detached from the main thread so other threads can interact with it.
In a little example:
#!/usr/bin/python2.4
import threading
import time
class Sample(threading.Thread):
def __init__(self):
super(Sample, self).__init__()
self.status = 1
self.stop = False
def run(self):
while not(self.stop):
pass
def getStatus(self):
return self.status
def setStatus(self, status):
self.status = status
def test(self):
while self.status != 0:
time.sleep(2)
#main
sample = Sample()
sample.start()
sample.test()
sample.setStatus(0)
sample.stop()
What I'd like is having the "sample" instance running as a separate thread (detached from the main one) so, in the example, when the main thread reaches sample.test(), sample (and only "sample") would go to sleep for 2 seconds. In the meanwhile, the main thread would continue its execution and set sample's status to 0. When after the 2 seconds "sample" wakes up it would see the status=0 and exit the while loop.
The problem is that if I do this, the line sample.setStatus(0) is never reached (creating an infinite loop). I have named the threads, and it turns out that by doing this, test() is run by the main thread.
I guess I don't get the threading in python that well...
Thank you in advance
The object's run() method is what executes in a separate thread. When you call sample.test(), that executes in the main thread, so you get your infinite loop.
Perhaps something like this?
import threading
import time
class Sample(threading.Thread):
def __init__(self):
super(Sample, self).__init__()
self.stop = False
def run(self):
while not(self.stop):
print('hi')
time.sleep(.1)
def test(self):
print('testing...')
time.sleep(2)
#main
sample = Sample()
sample.start() # Initiates second thread which calls sample.run()
sample.test() # Main thread calls sample.test
sample.stop=True # Main thread sets sample.stop
sample.join() # Main thread waits for second thread to finish

Categories