Python Threading Parameters Issue - python

I've been trying for around half an hour now and just cant seem to wrap my head around what im doing wrong here.
Working Code:
import threading
from time import sleep
def printX():
threading.Timer(5.0, printX).start()
print("five")
printX()
while True:
print("1")
sleep(1)
This works, however I need to be able to dynamically assign what the print statement will be along with the delay.
Desired Code:
import threading
from time import sleep
def printX(time, message):
threading.Timer(int(time), printX).start()
print(str(message)
printX(time, message)
while True:
print("Rest of the program continues")
sleep(1)
Thanks for any help in advance :).

threading.Timer could pass arguments with args:
threading.Timer(int(time), printX, (time, message)).start()
read more on its doc.

An alternative method is to define a class with printX as an inner function.
class thread:
def __init__(self, time, message):
self.time = time
self.message = message
def printX(self):
threading.Timer(int(self.time), self.printX).start()
print(str(self.message))
thread(3,"test message").printX()
while True:
print("Rest of the program continues")
sleep(1)

Related

Creating processes that contains infinite loop in python

I want to create processes without waiting for other processes finish which they can't because they are in an infinite loop.
import time
from multiprocessing import Process
def child_function(param1, param2):
print(str(param1 * param2))
while True:
print("doing some stuff")
time.sleep(3)
def main_function():
print("Initializing some things.")
for _ in range(10):
Process(target=child_function(3, 5)).start()
if __name__ == '__main__':
main_function()
This code only starts one process and waits for it to finish. How can I do this?
Edit: Comment answer works fine and the answer below also works fine but for creating thread. Thank you everyone.
Try this Python module Threading
import time
import threading
def child_function(param1, param2):
print(str(param1 * param2))
while True:
print("doing some stuff")
time.sleep(3)
def main_function():
print("Initializing some things.")
for _ in range(10):
x = threading.Thread(target=child_function, args=(3,5, ))
x.start()
main_function()
Explanation: as already mentioned in the comments, notice that we are passing the function as opposed to calling it via the thread constructor, Also you can compare Threading vs Multiprocessing and use whichever best suits the project.

Python: how to set a time to trigger a function?

How can I set a timer to run a function? right now I manually run the function. But what if I want to tell Python to run it in like 1 hour? how can I achieve this task?
Additionally, how about trying to run it at say 5pm today or tomorrow?
I tried the following but does not really work. What did I miss?
import datetime
from threading import timer
def hello_world():
print("hello world")
delta_t = datetime.time(0,1,0)
Timer(delta_t, hello_world)
import threading
def task():
print("hello world ")
timer = threading.Timer(5.0, task)
timer.start()

Scheduling tasks in Python

import schedule
import time
def job(work):
print(work)
schedule.every().day.at("10:30").do(job(work))
while True:
schedule.run_pending()
time.sleep(1)
How to call job(work) inside my do() function. if i give job() it works fine, but if i give job(work) it throwing error. what to do with this? any help
This is in the schedule FAQ:
import schedule
import time
def job(work):
print(work)
schedule.every().day.at("10:30").do(job,work="") # make "" whatever string you want
while True:
schedule.run_pending()
time.sleep(1)

returning variables from a thread process function in Python 3

I'm working on a thread that updates a variable of the main process. As I did not succeed passing arguments I had to use global. But I don't like it, it's not safe. There is any way without using global?
I can pass the argument, but my issue is with the returning object.
My code:
#!usr/bin/python3
# -*- coding: UTF-8 -*-
import threading
import time
my_check = " CHECK " # TODO replace with initial source data.
class MiThread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
def run(self):
time.sleep(5)
print("I'm the SECOND thread")
global my_check
my_check = " CHECK DONE!!!" # TODO replace with the updated source data.
self.run()
print ("I'm the principal thread.")
t = MiThread()
t.start()
#t.join(1)
while True:
time.sleep(0.5)
print("I'm the principal thread, too." + my_check)
This is only a concept proof, really I want to code a little stocks ticker displayer in a tkinter label, and I need, at least two more threads: the updater thread (for update the information to display) and the displayer thread (it must changes the text of the label each 0.3 seconds).
You can store result of thread execution in instance variable of thread object:
import threading
import time
class MiThread(threading.Thread):
def __init__(self):
self.my_check = " CHECK "
threading.Thread.__init__(self)
def run(self):
time.sleep(5)
print("I'm the SECOND thread")
self.my_check = " CHECK DONE!!!"
print ("I'm the principal thread.")
t = MiThread()
t.start()
while True:
time.sleep(0.5)
print("I'm the principal thread, too." + t.my_check)

simple thread management within python classes

Im trying to write a module for Python that prints out text for my program and displays a progress bar while i do something in the background. Im using the 'threading' module currently but open to suggestions if something else will make it easier.
what i want to know is two fold, how should i call this class elegantly and how should i stop these threads im creating?
this is what im currently doing:
tmp1 = textprint("hello this is text")
tmp1.start()
# do something
tmp1.stop()
these are the options ive considered and looked into so far:
using thread.name to find the name of the thread or having the thread
return a name to kill afterwards. OR passing a number for similar
thread identification afterwards. (a bit cumbersome and not my
favourite solution.)
sending a thread.event ? - from reading the docs i see an event can
be sent, perhaps that can be used to stop it?
or a with statement but im unclear how to use it in this context, plus i find most of the python docs extremely confusing and not written for me at all.
what i would like to do is something like this:
echo('hello') (prints progress bar etc)
- and then when i want to stop it echo.stop()
the obv. problem there though is that the stop function doesnt know which thread it is trying to stop.
Here is a skeleton of what im trying to do:
import time
import string
import threading
class print_text(threading.Thread):
def __init__(self,arg=None):
super(print_text,self).__init__()
self._stop = False
self.arg=arg
def run (self):
# start thread for text
print self.txt
while not self._stop:
print "rude words"
def echo (self,txt):
self.txt=txt
self.start()
def stop(self):
self._stop = True
def stopped(self):
return self._stop == True
def __enter__(self):
print "woo"
return thing
def __exit__(self, type, value, traceback):
return isinstance(value, TypeError)
if __name__ == '__main__':
print_text.start.echo('this is text') # dunt werk
with print_text.echo('this is text'):
time.sleep(3)
print "done"
and then call it like so:
echo('this is text')
i also guess to do this i would have to
import echo from print_text
the WITH way of doing things suggests putting an __enter__ and __exit__ bit in. i tried them and they didnt work and also, i didnt know what i was doing, really appreciate any help, thanks.
You were very close to having working code. There just needed to be a few minor fixups:
print_text is a class. It should be instantiated with print_text()
The start method returns an instance of print_text, you need to save that
in order to call stop and echo on it: t = print_text()
The enter method needs to return self instead of thing.
The exit method should either set _stop or call stop().
The echo method should return self so that it can be used with the with-statement.
Here is some working code that includes those minor edits:
import time
import string
import threading
class print_text(threading.Thread):
def __init__(self, arg=None):
super(print_text,self).__init__()
self._stop = False
self.arg=arg
def run (self):
# start thread for text
print self.txt
while not self._stop:
print "rude words"
def echo (self, txt):
self.txt=txt
self.start()
return self
def stop(self):
self._stop = True
def stopped(self):
return self._stop == True
def __enter__(self):
print "woo"
return self
def __exit__(self, type, value, traceback):
self._stop = True
return isinstance(value, TypeError)
if __name__ == '__main__':
t = print_text()
t.echo('this is text')
time.sleep(3)
t.stop()
with print_text().echo('this is text'):
time.sleep(3)
print "done"
The best way to stop a thread in Python is to politely ask it to stop. The best way to pass new data to a thread is with the Queue module.
Both are used in the code in this post, which demonstrates socket communication from a Python thread but is otherwise relevant to your question. If you read the code carefully you'll notice:
Using threading.Event() which is set by a method call from outside, and which the thread periodically checks to know if it was asked to die.
Using Queue.Queue() for both passing commands to the thread and receiving responses from it.
A thread name is useful if you could potentially have multiple subthreads running the same target at once and want to ensure that all of them are stopped. It seems like a useful generalization and doesn't seem too cumbersome to me, but beauty is in the eye of the beholder :-). The following:
starts a subthread to print a message and start a progressbar
stops the subthread using a name given when it was started.
It is much simpler code. Does it do what you want?
import time, threading
class print_text:
def __init__(self):
pass
def progress(self):
while not self._stop: # Update progress bar
print(".", sep="", end="")
time.sleep(.5)
def echo(self, arg="Default"): # Print message and start progress bar
print(arg)
self._stop = False
threading.Thread(target=self.progress, name="_prog_").start()
def stop(self):
self._stop = True
for t in threading.enumerate():
if t.name == "_prog_":
t.join()
tmp1 = print_text()
tmp1.echo("hello this is text")
time.sleep(10)
tmp1.stop()
print("Done")

Categories