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

p.wait() doesn't block #154

Closed
runeksvendsen opened this issue Sep 26, 2013 · 3 comments
Closed

p.wait() doesn't block #154

runeksvendsen opened this issue Sep 26, 2013 · 3 comments

Comments

@runeksvendsen
Copy link

Take a look at this example:

from sh import mpv
import multiprocessing, time

class MpvPlay:
    CACHE_SIZE = 4096

    def __init__(self, url, exit_callback=None):
        self.url = url
        self.exit_callback = exit_callback

    def play(self):
        self.p = mpv(self.url, cache=self.CACHE_SIZE, no_video=True, _bg=True)

        self.process = multiprocessing.Process(target=self.process_thread)
        self.process.start()

    def process_thread(self):
        try:
            print "MpvPlay thread: waiting"
            self.p.wait()
        except Exception, e:
            pass

        print "MpvPlay thread: executing callback"
        if self.exit_callback:
            self.exit_callback(self.p)

def exit_callback(p):
    print "MPV exited. stdout:\n\t%s" % (p.stdout)

if __name__ == "__main__":
    url="https://www.youtube.com/watch?v=nKAVpoPjEJ8"
    playobj = MpvPlay(url, exit_callback)
    playobj.play()

    while True:
        time.sleep(1)

As far as I can see, this should start the program "mpv" (you can substitute with "mplayer" is you don't have mpv installed), and after the program exits it should execute the exit_callback function. But the exit_callback function is executed immediately, while mpv is still running. Shouldn't self.p.wait() block in process_thread(), so exit_callback isn't called until mpv exits?

@miohtama
Copy link

If it's a GUI application some applications tend to return to command line immediately and not block (some kind of daemonization). In this case, you should check from the application itself what it is doing and if there is a command-line flag to prevent this behavior.

@runeksvendsen
Copy link
Author

@miohtama With the --no-video (no_video=True) option it's not a GUI application, and even when it is it doesn't return from the command line until you close the video window.

@amoffat
Copy link
Owner

amoffat commented Dec 29, 2014

this is super old, but I'll attempt to answer it...

the problem was concealed by:

        try:
            print "MpvPlay thread: waiting"
            self.p.wait()
        except Exception, e:
            pass

a valid exception was being thrown, but it was ignored. that exception was OSError: [Errno 10] No child processes. the reason for this was because you ran a multiprocessing.Process and tried to wait() on a process that wasn't it's child process (it was a sibling process at this point). so that exception was thrown and your callback was called, while the process happily played the video.

it seems like you did this in order to use an exit callback when the spawned process finishes. good news is, exit callbacks have been added in the release-1.10 branch which should go out before the end of the year

@amoffat amoffat closed this as completed Dec 29, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants