#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2013
    Posts
    2
    Rep Power
    0

    Parallel printing in python


    Wrote the following script to get scrolling text printed on multiple lines on a terminal running in a linux box:


    Code:
    import os, sys, time
    import threading
    import curses
    
    def scroll_text(content, line, scroll_limit, sleep_time):
        blank_line = "\r" + " " * scroll_limit
        buf = ""
    
        if line > 0:
            sys.stdout.write("\r\n" * line)
            sys.stdout.flush()
        for cindex in range(0, len(content), 1):
            sys.stdout.write(blank_line)
            sys.stdout.flush()
            buf = content[cindex:cindex + scroll_limit]
            for itr in range(0, len(buf), 1):
                if buf[itr] == "\n":
                    buf[itr] = "-"
            buf = "".join(buf)
            if buf != "":
                sys.stdout.write("\r" + buf)
                sys.stdout.flush()
    
            time.sleep(sleep_time)
       
    fdo = open('output.txt', 'w')
    
    fd = open('chat.txt', 'r')
    content = fd.read()
    
    content_list = list(content)
    content1 = content_list
    content2 = content_list
    
    fd.close()
    
    thread1 = threading.Thread(target=scroll_text, args=(content1, 0, 70, 0.05))
    thread2 = threading.Thread(target=scroll_text, args=(content1, 1, 70, 0.05))
    thread1.start()
    thread2.start()
    thread1.join()
    thread2.join()
    Noticed that the threads are not running in parallel. Read somewhere that we must use multiprocessing module with Pool() method called. Noticed that even that results in same behavior. Request to please help me know whether my understanding is correct or not
  2. #2
  3. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,995
    Rep Power
    481
    I halved the scrolling position in one thread. Flickering cursor shows both threads running.

    The terminal emulation software doesn't know multiple threads are running. It maintains only 1 current position. If you want separate scrolling on several lines you'll need to dig into that curses module you imported and maybe even synchronize the display section of the code so only one thread at a time accesses the critical section.
    [code]Code tags[/code] are essential for python code and Makefiles!
  4. #3
  5. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2013
    Posts
    2
    Rep Power
    0

    curses way


    Thanks b49P23TIvg

    Tried the curses way. Looks like this has gone a little further, but there is gibberish on screen.

    Here is the curses code:

    Code:
    import os, sys, time
    import threading
    import curses
    
    def report(line_no, text):
            stdscr.addstr(line_no, 0, text)
            stdscr.refresh()
    
    def scroll_text(content, line, scroll_limit, sleep_time):
    	itr1 = 0
    	for itr in range(0, len(content) - 1, 1):
    		if content[itr] == "\n" or content[itr] == "\r\n":
    			content[itr] = '-'
    
    	report(line, "\r" + " " * scroll_limit + "\r")
    	for itr in range(0, len(content), 1):
    		buf = "".join(content[itr:itr + scroll_limit])
    
    		buf = buf.rstrip()
    
    		if buf != "":
    			report(line, "\r" + buf)
    		time.sleep(sleep_time)
    	
    
    fd = open('chat.txt', 'r')
    content = list(fd.read())
    fd.close()
    
    stdscr = curses.initscr()
    curses.noecho()
    curses.cbreak()
    
    try:
    	thread1 = threading.Thread(target=scroll_text, args=(content, 0, 70, 0.05))
    	thread2 = threading.Thread(target=scroll_text, args=(content, 1, 70, 0.05))
    	thread1.start()
    	thread2.start()
    	thread1.join()
    	thread2.join()
    
    except:
    	curses.echo()
    	curses.nocbreak()
    	curses.endwin()
    finally:
    	curses.echo()
    	curses.nocbreak()
    	curses.endwin()
    Here is the video
    Video URL: http://hidemyass.com/files/fsyxv/
  6. #4
  7. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,995
    Rep Power
    481
    I removed your '\r''s and added a lock for synchronization., changed the input file from chat to the program source, and the output was still messy. So I replaced curses with direct ANSI terminal control sequences, now works well.
    Code:
    #with ANSI sequences directly
    import os, sys, time
    import threading
    
    def report(line_no, text):
        csi = '%c['%27
        print('{}{};{}H{}K{}'.format(csi,line_no,1,csi,text))
    
    def scroll_text(content, line, scroll_limit, sleep_time, lock):
        itr1 = 0
        for itr in range(0, len(content) - 1, 1):
            if content[itr] == "\n" or content[itr] == "\r\n":
                content[itr] = '-'
        lock.acquire()
        report(line, " " * scroll_limit)
        lock.release()
        for itr in range(0, len(content), 1):
            buf = "".join(content[itr:itr + scroll_limit])
            buf = buf.rstrip()
            if buf != "":
                report(line, buf)
            time.sleep(sleep_time)
    
    
    fd = open('p.py')
    content = list(fd.read())
    fd.close()
    
    try:
        Locke = threading.Lock()
        thread1 = threading.Thread(target=scroll_text, args=(content, 3, 70, 0.05, Locke))
        thread2 = threading.Thread(target=scroll_text, args=(content, 7, 70, 0.05, Locke))
        thread1.start()
        thread2.start()
        thread1.join()
        thread2.join()
    except:
        pass
    [code]Code tags[/code] are essential for python code and Makefiles!

IMN logo majestic logo threadwatch logo seochat tools logo