A different way to implement this streaming processing?

I am testing threads in python. I want the rotating cursor to appear when another method starts (within 5-10 minutes). I made some code, but I wonder how you will do it? I do not like to use global variables, so I assume there is a better way?

c = True def b(): for j in itertools.cycle('/-\|'): if (c == True): sys.stdout.write(j) sys.stdout.flush() time.sleep(0.1) sys.stdout.write('\b') else: return def a(): global c #code does stuff here for 5-10 minutes #simulate with sleep time.sleep(2) c = False Thread(target = a).start() Thread(target = b).start() 

EDIT:

Another problem is that when processing is complete, the last element of the rotary cursor is still on the screen. so something like \ printed.

+4
source share
3 answers

You can use events: http://docs.python.org/2/library/threading.html

I tested this and it works. It also syncs everything. You should avoid changing / reading the same variables in different threads without synchronizing them.

 #!/usr/bin/python from threading import Thread from threading import Event import time import itertools import sys def b(event): for j in itertools.cycle('/-\|'): if not event.is_set(): sys.stdout.write(j) sys.stdout.flush() time.sleep(0.1) sys.stdout.write('\b') else: return def a(event): #code does stuff here for 5-10 minutes #simulate with sleep time.sleep(2) event.set() def main(): c = Event() Thread(target = a, kwargs = {'event': c}).start() Thread(target = b, kwargs = {'event': c}).start() if __name__ == "__main__": main() 

Associated with 'kwargs', from Python docs (URL at the beginning of the post):

 class threading.Thread(group=None, target=None, name=None, args=(), kwargs={}) ... kwargs is a dictionary of keyword arguments for the target invocation. Defaults to {}. 
+3
source

Basically you are on the right track, with the exception of the global variable. Usually you would need to coordinate access to shared data like this with a lock or semaphore, but in this special case you can do a short cut and just use whether one of the threads is working or not. Here is what I mean:

 from threading import Thread from threading import Event import time import itertools import sys def monitor_thread(watched_thread): chars = itertools.cycle('/-\|') while watched_thread.is_alive(): sys.stdout.write(chars.next()) sys.stdout.flush() time.sleep(0.1) sys.stdout.write('\b') def worker_thread(): # code does stuff here - simulated with sleep time.sleep(2) if __name__ == "__main__": watched_thread = Thread(target=worker_thread) watched_thread.start() Thread(target=monitor_thread, args=(watched_thread,)).start() 
+3
source

This is not properly synchronized. But I will not explain everything to you now, because it is a lot of knowledge. Try reading this: http://effbot.org/zone/thread-synchronization.htm

But in your case, it’s not so bad that things are not synchronized. The only thing that can happen is that the spindle shaft rotates a few ms longer than required in the background task.

+1
source

Source: https://habr.com/ru/post/1480434/


All Articles