Good day. there is a script, it runs the same function in 5 threads using threading. The function is paused under certain conditions time.sleep. BUT! the remaining 4 threads continue to work. How to make so that all 5 threads get paused?
- You can make a common variable and check it in each thread. You can send a parameter to the threads through the queue . - Sergey Gornostaev
- @ sergey-gornostaev also already thought about a common variable, so it will probably be easier, thanks! - Igor Zhdanov
- Semaphore is called.) See the modules threading . - eri
- oneAnd it seems to me that docs.python.org/3/library/threading.html#condition-objects is closer to this topic even though it is a bit odd in my bell tower. - vitidev
|
3 answers
To stop iterations in a function at each triggering of a condition in any of the threads for 5 seconds (for each triggering):
#!/usr/bin/env python3 """Stop all threads for 5 seconds if some condition happens.""" import random import threading import time def safe_write(s, lock=threading.Lock()): with lock: print(s, end="", flush=True) def worker(char, started: threading.Event, lock=threading.Lock()): while started.wait(): safe_write(char) # do some work if random.random() < .025: # if some condition # pause for 5 seconds with lock: # the pauses are consecutive if the condition # triggers in more than one thread started.clear() # this stops cycles in all threads try: safe_write(" wait") for c in ".....": safe_write(c) time.sleep(1) safe_write("continue\n") finally: started.set() # start the cycles again else: time.sleep(.1) started = threading.Event() for char in "12345": threading.Thread(target=worker, args=[char, started], daemon=True).start() print("Press Enter to exit", flush=True) started.set() # start all cycles input() This can be implemented using a more primitive object, such as threading.Condition() :
#!/usr/bin/env python3 -u """Stop all threads for 5 seconds if some condition happens.""" import random import threading import time def worker(char, cv=threading.Condition()): can_run = True while True: safe_write(char) # do some work if random.random() < .025: # if some condition # pause for 5 seconds with cv: # the pauses are consecutive if the condition triggers in more than one thread can_run = False # this stop cycles in all threads try: safe_write(" wait V seconds") for c in ".....": safe_write(c) time.sleep(1) safe_write("continue\n") finally: can_run = True # start the cycles again cv.notify_all() else: time.sleep(.1) with cv: # wait until we can run while not can_run: cv.wait() print("Press Enter to exit", flush=True) for char in "12345": threading.Thread(target=worker, args=[char], daemon=True).start() input() |
lock=threading.Lock() in threads:
lock.acquire() time.sleep(5) lock.release() - Can you set an example of use? To be able to run and see - gil9red
- Kst, your example can be simplified through with-expression: docs.python.org/3/library/… - gil9red
|
import threading from datetime import datetime import time def job(p): global lock lock.acquire() for i in range(0,5): print p, datetime.now().strftime('%H:%M:%S'), threading.currentThread().getName() time.sleep(1) lock.release() lock=threading.Lock() for i in range(0,3): t=threading.Thread(target=job, args=(i,)) t.start() t.join() global lockwhy do we need aglobal? - gil9red- Your function is strictly consistently executed. - jfs
- That's right, because every thread in the example has a pause. Of course, this pause should be called conditionally. I just showed how to use object lock - user2702614
- One lock for the task is not enough. Look at the code in my answer. If you think that's enough, then demonstrate how to stop all threads [for a while] at the same time when a condition is triggered in any one thread. - jfs
|