I cant start 2 separated threads on 1 connection to server.
I want run 2 functions in loop, it looks like they are executed one by one.
Are there any other option to run functions every x seconds/min?
Threading is good tool to use?
import time
import datetime
from threading import Thread
def func1(ts3conn):
print(f"func 1, pause 2sec NOW:{datetime.datetime.now()}")
time.sleep(2)
def func2(ts3conn):
print(f"func2, pause 10sec NOW:{datetime.datetime.now()}")
time.sleep(10)
if __name__ == "__main__":
with ts3.query.TS3ServerConnection("telnet://serveradmin:passwod#1.2.3.4:10011") as ts3conn:
ts3conn.exec_("use", sid=1)
ts3conn.exec_("clientupdate", client_nickname="BOT")
while True:
Thread(target=func1(ts3conn)).start()
Thread(target=func2(ts3conn)).start()
func 1, pause 2sec NOW:2019-08-24 23:53:19.139951
func2, pause 10sec NOW:2019-08-24 23:53:21.141273
func 1, pause 2sec NOW:2019-08-24 23:53:31.141770
func2, pause 10sec NOW:2019-08-24 23:53:33.142568
func 1, pause 2sec NOW:2019-08-24 23:53:43.143090
func2, pause 10sec NOW:2019-08-24 23:53:45.143880
The target parameter expects a callable (i.e. function), but you're passing the result of calling that callable and the sleep is occurring before the thread is even created.
So instead of this:
Thread(target=func1(ts3conn)).start()
... try something like this:
Thread(target=func1, args=(ts3conn,)).start()
Unfortunately when you fix this issue you're going have another problem: the while loop is not going to wait for the threads to finish before creating new threads, and will continue creating new threads until the application crashes. You may want to try something like this:
while True:
t1 = Thread(target=func1, args=(ts3conn,))
t2 = Thread(target=func2, args=(ts3conn,))
t1.start()
t2.start()
# wait for the threads to finish
t1.join()
t2.join()
Related
I want to execute a task after certain time, so I have tried a countdown timer with a condition of being finished (when countdown variable = 0, the task is performed). The thing is that I don't want to stop the execution of the main program while performing the countdown. I have tried this:
import time
def countdown(num_of_secs):
while(num_of_secs):
time.sleep(1)
num_of_secs -= 1
return num_of_secs
So, I run my code setting a number of seconds to the countdown, and when this countdown reaches the 0 value, a task must be executed. Using this code (it uses a while), when I call my function "countdown" it stops the execution of the main program, so it is the same as a big time.sleep. I want to carry out this countdown in the background, without stopping other actions until the countdown finishes and the task starts.
Thank you
Another alternative is by using threading.
I've got a simple example here with 2 Threads where the working thread is waiting for the countdown thread to finish and starting. The Main is still working fine.
import threading
import time
def do_something():
countdown_thread.join()
print("Starting Task")
time.sleep(3)
print("Finished Task")
def countdown(num_of_secs):
while(num_of_secs):
time.sleep(1)
num_of_secs -= 1
print(num_of_secs)
if __name__ == '__main__':
countdown_thread = threading.Thread(target=countdown, args=(3,))
work_thread = threading.Thread(target=do_something)
countdown_thread.start()
work_thread.start()
while True:
print("Main doing something")
time.sleep(1)
Example picture for multithreading: Sequential vs Threading
Usually python only has a single program flow, so every instruction needs to complete before the next one can get executed.
For your case you need asynchronicity, with e.g. asyncio.sleep(5) as a separate task in the same event loop.
import asyncio
async def sleeper():
print('Holding...')
await asyncio.sleep(5)
print('Doing Work!')
async def work():
print('Doing work')
print('while')
print('the other guy is sleeping')
async def main():
await asyncio.gather(sleeper(), work())
asyncio.run(main())
The most common and easiest way to implement this would be with a Timer object from the threading library. It would go as follows:
import threading
import time
i = 0
done = False
def show_results():
print("results from GPIO readings")
print("=)")
global done
done = True # signal end of while loop
def read_GPIO():
print("reading GPIO...")
t = threading.Timer(60, show_results) # task will trigger after 60 seconds
t.start()
# your while loop would go here
read_GPIO() # do work
while not done:
print("waiting", i) # doing work while waiting for timer
time.sleep(1)
i += 1
pass
Notice that the time library is used only for illustrative purposes. You could also start the timer recursively to check periodically GPIOs and print results or trigger an event. For more information on the threading library or the Timer object check the docs
I wrote proxy checker and I need to automate checking for every 5 minutes. My while True loop skips the functions. When I have first iteration - functions are running, but with next iterations they are skipped, just printing START!!!!!! and END---- in my console.
if __name__ == "__main__":
while True:
print("START!!!!!!!!!!")
http_proxy_check()
save_proxy('http')
print("END------------------")
time.sleep(2)
http_proxy_check function:
def http_proxy_check():
for proxy in http_proxyList:
print(f"Checking {http_proxyList.index(proxy)} of {len(http_proxyList)} element")
thread = Thread(target=checkIp_http,args=(proxy.strip(), ))
if len(threads)<=1200 :
thread.start()
threads.append(thread)
else:
threads.clear()
for thread in threads:
thread.join()
You are directly trying to run subthreads. Why are you not using multiprocess?
Also you can try to "timeloop" library for periodic tasks;
https://pypi.org/project/timeloop/
pip install timeloop
import time
from timeloop import Timeloop
from datetime import timedelta
tl = Timeloop()
#tl.job(interval=timedelta(minutes=5))
def sample_job_every_5m():
print "5m job current time : {}".format(time.ctime())
while True: # infinite loop
your_code_that_process() # put your code that do stuff once and exit
time.sleep(5*60) # 300 seconds of sleeping, make it wait 300sec
if check_for_abort_if_so_break(): # you can make flag that you trigger on error or by input
# so you can exit out of infinite loop
break # exit infinite loop (not so infinite anymore)
i wrote a code in python with 2 infinite loop like this:
import threading
import time
ticker = 0
def ticking():
global ticker
while True:
time.sleep(1)
ticker +=1
print("ticker = {}".format(ticker))
def main_line():
while True:
print("Hello world")
time.sleep(4)
t1 = threading.Thread(target = ticking)
t2 = threading.Thread(target = main_line)
t1.start()
t2.start()
#t1.join()
if __name__ == "__main__":
t1.join()
#t2.join()
If i don't join any thread it's not working, but when i join 1 thread, another thread is work too but i don't know why?
Can anyone explain for me?
Join is used to block the calling method until the thread finishes, throws an exception or time out.
join([timeout]) Wait until the thread terminates. This blocks the
calling thread until the thread whose join() method is called
terminates – either normally or through an unhandled exception – or
until the optional timeout occurs.
In your case, you have started both threads. So both threads are working. But once you block the main thread by t1.join(), both running threads will be visible.
it is because you also "start" another thread. If you make a comment on t2.start(), then the thread is only working on t1.
t1.start()
# t2.start()
I've been looking all over google and can't seem to get this working.
I'm trying to thread 2 functions, both of which are infinite loops.
Looking at the extract below, it only starts the 1st thread and does not proceed to the next one in line.
PS: When I swap the 2 threads around, then I have the same problem with the 2nd thread.
def syslog_service():
syslog_server = socketserver.UDPServer((syslog_host,syslog_port), Syslog_Server)
syslog_server.serve_forever()
def cleanup_old_logs_service():
# lock = threading.Lock()
# threading.Thread.__init__(self)
global syslog_retention_hours
global RUNNING
while RUNNING:
# cleanup_old_logs_service.lock.acquire()
cleanup.old_logs(syslog_retention_hours)
# cleanup_old_logs_service.lock.release()
time.sleep(10)
if __name__ == "__main__":
try:
logger.info("Starting main thread")
config()
logger.info("Starting system testing")
test()
logger.info("Config loaded")
thread1 = cleanup_old_logs_service()
thread2 = syslog_service()
thread1.start()
logger.info("Syslog cleanup service running")
thread2.start()
logger.info("Syslog server running")
The reason why only the first thread is executed is that you actually have ONLY one thread in your program. When you write thread1 = cleanup_old_logs_service() and thread2 = syslog_service()you are not creating new threads, but just assigning the return values of your functions to 2 different variables. For this reason, as soon as the program encounters thread1, it executes cleanup_old_logs_service() and gets stuck in an infinite loop.
To create a new thread, I would import the threading module, create a new threadObj object and start the thread as follows:
import threading
threadObj = threading.Thread(target=cleanup_old_logs_service)
threadObj.start()
This way, the function cleanup_old_logs_service() will be executed in a new thread.
By saying thread1 = cleanup_old_logs_service() you are actually executing the function cleanup_old_logs_service not saving a reference to a thread. You would have to say
import threading # If you have not already
thread1 = threading.Thread(target=cleanup_old_logs_service)
thread2 = threading.Thread(target=syslog_service)
# Now you can start the thread
thread1.start()
logger.info("Syslog cleanup service running")
thread2.start()
logger.info("Syslog server running")
You can look at https://docs.python.org/3.5/library/threading.html for documentation and https://pymotw.com/2/threading/ for examples, because I believe you would need to use locks to manage access to your resources
This question already has answers here:
Terminate multiple threads when any thread completes a task
(5 answers)
Closed 8 years ago.
Is it possible to run two threads simultaneously? For example...
I have two classes like this...
import threading
class Thread1(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
def run(self):
print("Thread1")
class justAClass(object):
def do_soemthing(self):
print("Thread2")
if __name__ == "__main__":
total = 0
thread_limit = 200
while True:
if threading.activeCount() < thread_limit:
Thread1().start()
# I will never run because I want to wait until while True has finished to run!
t = threading.Timer(1.0, justAClass().do_soemthing())
t.start()
If you run this code you will see that Tread2 never gets printed out because the Thread2 has to wait for Thread1 to finished (which it never will because of the While statement.
What I'm after is for both Thread1 and Thread2 to run at the same time independent of each other.
while True:
if threading.activeCount() < thread_limit:
Thread1().start()
# I will never run because I want to wait until while True has finished to run!
t = threading.Timer(1.0, justAClass().do_soemthing())
t.start()
obviously that's the case! And as you're never getting out of the loop, the code below the comment is unreachable.
Though, your first code was:
tor.connect()
tor.new_identity()
t = threading.Timer(10.0, tor.new_identity())
t.start()
total = 0
thread_limit = 200
while True:
if threading.activeCount() < thread_limit:
stress_test(host_ip, host_port).start()
And there you were initiating the Timer before the infinite loop, so your Timer thread was definitely working, as we said in our comments. To make your SSCCE work correctly, here comes the fix:
import threading
import time
class Thread1(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
def run(self):
time.sleep(1)
print("Thread1")
class justAClass(object):
def do_something(self, pause):
while True:
time.sleep(pause)
print("Thread2XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
if __name__ == "__main__":
total = 0
thread_limit = 200
t = threading.Timer(1.0, justAClass().do_something, args=(1.0,))
t.start()
while True:
if threading.activeCount() < thread_limit:
Thread1().start()
Though, be aware that your timer thread, with the do_something function as it is, will only run once, unless you rearm it from within the thread, or you build a while loop within.
BTW, I fixed another mistake in your code I did not see at first, you're calling the
timer over the do_something function, be if you pass the do_something function with
parens at the end do_something(), it will be evaluated in your main thread as you're
creating the timer, and then you'll be passing the result of the function to the Timer
function... Whereas if you do not use the parens, you're giving the function object itself
to Timer() which will then be able to call it after the delay.
is there a way to get the timer to run every x seconds while still allowing the other function to run?
of course:
class justAClass(object):
def do_something(self, pause):
while True:
time.sleep(pause)
print("Thread2XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")