Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Blessed is not thread safe which messes the ouput on multiple terminal.location #214

Open
hash3liZer opened this issue Aug 11, 2021 · 3 comments

Comments

@hash3liZer
Copy link

First of all, it's really a great library and kudos to the development. I've integrated this library in a project of mine where multiple threads are printing on the terminal at the same time. Consider these two functions:

import progressbar
from blessed import Terminal
import time

term = Terminal()

def fucn1():
    with term.location(0, 5):
        for n in progressbar.progressbar(range(100)):
            time.sleep(0.3)

def func2():
    with term.location(0, 10):
        for n in progressbar.progressbar(range(10000)):
            time.sleep(0.3)

Now, if you run these functions simulataneously using threads (a couple times to make sure), you will see sometimes each bar is overlapped on the other bar. Which means that the functions being called are not thread safe. And calling multiple lines at the same time will mess the output.

@jquast
Copy link
Owner

jquast commented Aug 11, 2021

Well, blessed is thread safe, I have successfully used it in a threaded terminal server project serving each client ip it’s own output (telnet 1984.ws a public server), It hasn’t any thing to do with threads, just that the file descriptor (sys.stdout) is shared. If you removed the threads and used asyncio, for example, it would have the same problem.

https://ejrh.wordpress.com/2011/09/18/output-synchronisation-in-python/

in blessed docs we say, “calls to location() may not be nested”, calling it twice on the same file descriptor is an example of “nesting”, the use of threads just makes it appear logically separate, I’m sorry this wasn’t clear, maybe we can add some documentation

These context managers have the side effect of printing hidden terminal sequences to the screen that are interpreted by the terminal, it can only handle one location sequence

@hash3liZer
Copy link
Author

Well, i guess that explains the messed up terminal. I found a quick solution though by putting all the location related statements under the same class and used a class variable to determine if another location context wrapper is being used somewhere. If it is, then while True: pass. Otherwise, go on.

I think adding that to the documentation would be very helpful. I don't know if i should close this right now or not though i found my answer. On to you from here.

@hash3liZer
Copy link
Author

Also, one more question, i had. It's a different one. Anyways, i am asking here. When i compile my script pyinstaller --noconsole option with blessed being used in the script, i get this error:

Failed to execute script

Without creating the terminal instance, i.e. term = Terminal(), it works all fine.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants