Hi, I am programming a simple application that does two tasks in parallel. First task is some sound processing using Ruby/GStreamer, while the second one is monitoring STDIN for commands changing way how sounds got processed. GStreamer uses GLib::Mainloop. I monitor STDIN using GLib::IOChannel, so it also uses GLib::Mainloop. How to make threading properly in this case? I need to interoperate between two threads, with no lockdowns (it's a part of critical system). I mean that when thread monitoring STDIN will receive some command it has to change some parameters of Gst pipeline ASAP, and when there would be some messages on the pipeline it should send them at STDOUT. Thanks in advance, m.
on 2009-12-06 16:35
on 2009-12-07 08:40
2009/12/7 Marcin Lewandowski <www@saepia.net>: > I am programming a simple application that does two tasks in parallel. > First task is some sound processing using Ruby/GStreamer, while the second > one is monitoring STDIN for commands changing way how sounds got processed. I don't understand why this needs to be done in two threads. As you say: > GStreamer uses GLib::Mainloop. I monitor STDIN using GLib::IOChannel, so it > also uses GLib::Mainloop. Remember that your computer doesn't actually do things in parallel. It allocates a little bit of time for one thread, works on it and then goes to another thread. But here you have GLib::Mainloop doing that for you. It will work on GStreamer stuff when it has it and will work on your IO when events come in. No matter what you do (even if you use threads) one thing will pause for a small amount of time while the other thing is happening. If you use a thread, you have no control over when that pause happens. It is almost always better to use something like GLib:Mainloop because you have control over the amount of processing that happens. If you are familiar with design patterns, this is known as a reactor pattern. I don't know exactly what you are doing, but I guess you want to do some long term processing with GStreamer and also handle IO at the same time. If that's the case, break down your processing in GStreamer into parts. Have Mainloop call your GStreamer processing and do one small part and then return. Repeat as necessary. You may have to create an object that holds the state of your processing so that it knows where to start up from. Since you say GStreamer is already integrated into Mainloop, I suppose this should usually happen without you needing to do much (???). At worst you may have to create a new GSource to handle your processing. I'm afraid I'm not familiar with either GStreamer, nor IOChannel, so I can't really help on the specifics. But I hope I'm pointing you in the right direction. I suspect that if you try to use a thread it will never work properly. If I have misunderstood what you were asking, please forgive me :-) MikeC
on 2009-12-07 21:36
Thanks for your answer. Well I thought that Gst would handle that task changing automatically, but as I can see both IOChannel and Gst are blocking. Is there any pretty way to implement what you have proposed? It's exactly what I need, but I don't know the syntax. m.
on 2009-12-08 09:06
2009/12/8 Marcin Lewandowski <www@saepia.net>: > Well I thought that Gst would handle that task changing automatically, but > as I can see both IOChannel and Gst are blocking. Hmmm... Well, I'm not sure what methods you're using, but I guess in IOChannel, for instance, you are using each_char(), etc. You have to use add_watch() instead. For example: add_watch(GLib::IOChannel::IN) do |channel, condition| string = channel.read() # parse the string here and do your output or whatever end Or instead of read() you can use readline() or readchar() until you catch the EOF exception. I'm not at all familiar with Gst, but looking at the tutorial it seems that the Bin::iterate() is what you want to call when you want to process incoming events (usually from the Pipeline). And I notice from a previous posting of yours that you already know how to add a watch from the bus (which doesn't seem to be documented anywhere???) But it seems that your problem is that you are calling mainloop.run and mainloop.stop. Instead, just run iterate() on the pipeline everytime you get an event. That should fix your problem. I hope :-) Like I said, I'm not familiar with these libraries. Hopefully someone who is will chime in (or maybe you're becoming the expert in the are ;-) ) MikeC
on 2009-12-08 11:24
Hi I don't have a solution to your problem. I mostly wanted to react to : 2009/12/7 Mike Charlton <mikekchar@gmail.com> > Remember that your computer doesn't actually do things in parallel. It > allocates a little bit of time for one thread, works on it and then goes > to another thread. > While this is true for a mono CPU computer, it might not be for dual or more. Moreover, his situation is quite particular. The thread waiting for IO is mostly sleeping. I agree though, that using GLib wake up mechanisms would be better in this case, than threading. However, if you need to react in 'realtime', and not 'very fast', GLib might not be the right library. Sorry, I'm not really helpfull. Simon
on 2009-12-08 16:17
> add_watch(GLib::IOChannel::IN) do |channel, condition| > string = channel.read() > # parse the string here and do your output or whatever > end Yes, I've did that already. And it's blocking. iterate doesn't exist any more in Gst m.
Please log in before posting. Registration is free and takes only a minute.
Existing account
(Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
Log in with Google account | Log in with Yahoo account
No account? Register here.