spx2 has asked for the wisdom of the Perl Monks concerning the following question:
use threads; $thr = threads->new(\&sub1); sub sub1 { while(1){ print "THREAD: in da zone !! :) \n\n"; sleep 1; }; } while(1){ my $stuff=''; read STDIN , $stuff,10; print "MAIN:", $stuff , "\n" ; }
maybe i should try to see if STDOUT can be written to and have a loop until it can be written instead of print "MAIN:", $stuff , "\n" ; i ask for your oppinions kind monks :)
Edit: g0n - code tags
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: perl threads wait application?
by BrowserUk (Patriarch) on May 18, 2007 at 05:31 UTC | |
Besides not bothering to format your post correctly, your question is so open to interpretation of your meaning that it is impossible to answer it properly, without you clarify what you are hoping to achieve? I suspect that when you run it, you are seeing an effect like this: Note: I've un-doubled the newlines for compactness.
That is, the output from the thread is interfering with your attempts to type input making it difficult to type and impossible to edit. Now one thing you can do is to serialise the use of the shared resource, the console, using a semaphore:
And you'll see something like this:
That will suspress output whilst you are typing which will make typing easier and editing possible. However, using read 10 will break up the input and cause it to be output in lumps of 10 characters and stop any less-than-10 characters residual at the end of the line from being displayed until you enter some more. So I suspect that isn't the complete answer to your badly asked question either. You can fix that problem by reading a line at a time. Insead of read, use readline or it's <STDIN> alias:
Now your input is displayed in the same way you entered it:
But, the input loop re-acquires the lock on the semaphore so quickly after each input completes that you never see any output (after the first batch) from the thread. Though if you have a multi-cpu system you might. To fix that, you need to relinquish the cpu, between reads. The addition of a sleep 1; to the read loop achieves that with this result:
Which is closer, but still probably not what you are hoping to achieve, because it means you won't see what the thread produces whilst you are typing until you finished typing. I suspect what you'd like, is for the output from the thread (but not what you are typing) to continue to scroll up the screen as you type. And for what you type to remain static at the bottom of the screen until you hit the enter key, whence it would be displayed amongst, and scroll with, the other output on the screen. Whilst leaving the prompt sitting waiting on the bottom of the screen for your next input. Here's the rub. To do that, you will have to control the cursor. Traditionally under unix this is done using ansi escape sequences, usually via curses or ncurses or some similar library. Though I suspect that those libraries are probably not re-entrant (thread safe), and using them in conjuction with multiple threads would be difficult, if not impossible. In any case, the win32 console doesn't do ansi escape sequences. It has it's own very powerful library of cursor and console control facilities. This is accessible via Win32::Console. The documentation for that module is sparse, relying mostly upon a link/reference to the MS documentation of the underlying APIs, but the MS website being what it is--every page/url getting changed/moved everytime someone in the management hierarchy gets promoted--the links are broken and relocating them (especially in the days before Google), seems to be quite hard. For reference, the current link is at Console Reference. There is also the extremely useful Term::ANSIScreen which sits on top of Win32::Console and emulates a subset of ansi escape sequences allowing some level of portability for applications that use them. This is thread-safe. Unfortunately, it doesn't emulate the most useful ansi (actually vt102, but adopted by ANSI ANSI X3.41-1974) escape sequence for doing the sort of thing I suspect you are trying to achieve, namely the SetScrollRegion. So where does all that leave you? It is definitely possible to achieve a static input line(s) and have the rest of the screen scroll. This can be done using ansi escape sequences (even without SetScrollRegion), though it is complicated. And more complicated in conjunction with multiple threads doing output. It is also possible (and somewhat easier in conjunction with threads) using Win32::Console. There are a couple of ways of tackling the problem.
Either approach is non-trivial. This is why people tend to use graphical interfaces (Tk etc.) for applications that require concurrent, asynchronous user input and application output. Writing code to handle controlled, asynchronous console IO for your application would require considerable effort to get right. Perhaps more effort than you are prepared to expend for your application. Ideally, this would be available as a module that you could just plug in and use, but the development would be even more non-trivial. Especially trying to come up with a good simple generic interface. I have had thoughts on this. The best idea I've come up with so far is that loading the module would override the STDIN, STDOUT & STDERR filehandles, replacing them with tie'd filehandles that would respond to all the usual operations they do, but would also allow each of them to be sized to some subregion of the screen. Or in the case of STDERR, perhaps a completely separate virtual screen that can be switched to, like a browser tab. All the serialisation, editing, history etc. can be completely hidden behind the STD(IN|OUT|ERR) interfaces. It's a simple and intuative interface that would place minimal design changes upon existing console applications. The problem is it would take considerable effort to get right and maintain, but how many people would make use of it? There doesn't seem to be a huge demand for this kind of thing. Developing such a beast for use by a handful of guys who want to write their own chat/irc clients is unappealing. Especially, when so many of them seem to be like you and cannot be bothered to formulate their questions well. Or even format their posts. Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
| [reply] [d/l] [select] |
|
Re: perl threads wait application?
by zentara (Cardinal) on May 17, 2007 at 17:27 UTC | |
I think your problem is your "read STDIN, $stuff,10" statement. It will wait for 10 chars, try "read STDIN,$stuff, 1". That works on linux. If you want readline on the stdin, try this
I'm not really a human, but I play one on earth. Cogito ergo sum a bum | [reply] [d/l] |
by BrowserUk (Patriarch) on May 17, 2007 at 18:14 UTC | |
Is there some reason for muddying the waters of this reply, with these 3 lines?
Instead of
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
| [reply] [d/l] [select] |
by zentara (Cardinal) on May 18, 2007 at 11:32 UTC | |
I'm not really a human, but I play one on earth. Cogito ergo sum a bum | [reply] |