Hello,
I have a program that needs to monitor different sockets for data
available for reading. I use select for this. I would like to be able to
type commands in the program, I figure I need to monitor STDIN as well.
Is it possible to use the GNU readline library in conjunction with this ?
--
luc wastiaux
|
|
0
|
|
|
|
Reply
|
luc
|
5/22/2004 3:11:59 PM |
|
luc wastiaux <dustpuppy@airpost.net> wrote:
> Hello,
> I have a program that needs to monitor different sockets for data
> available for reading. I use select for this. I would like to be able to
> type commands in the program, I figure I need to monitor STDIN as well.
> Is it possible to use the GNU readline library in conjunction with this ?
I would set STDIN in asynchronous mode instead. That will give you a signal
when you receive input from STDIN.
Something like this would do the trick
-------------------------------------------
if(fcntl(0, F_SETFL, O_ASYNC)<0) abort();
if(fcntl(0, F_SETOWN, getpid())<0) abort();
/* fcntl(0, F_SETSIG, SIGRTMIN+5); | You may want to use a realtime signal
instead of SIGIO */
signal(&your_sighandler, SIGIO /*SIGRTMIN+5*/)
int your_sighandler(int p) {
/* readline(...) */
}
-------------------------------------------
If you are monitoring the same socket constantly i would
advise you set it to async mode as well.
|
|
0
|
|
|
|
Reply
|
Viktor
|
5/22/2004 5:25:18 PM
|
|
Viktor Lofgren wrote:
>
> I would set STDIN in asynchronous mode instead. That will give you a signal
> when you receive input from STDIN.
>
> Something like this would do the trick
> -------------------------------------------
> if(fcntl(0, F_SETFL, O_ASYNC)<0) abort();
> if(fcntl(0, F_SETOWN, getpid())<0) abort();
> /* fcntl(0, F_SETSIG, SIGRTMIN+5); | You may want to use a realtime signal
> instead of SIGIO */
> signal(&your_sighandler, SIGIO /*SIGRTMIN+5*/)
>
> int your_sighandler(int p) {
> /* readline(...) */
> }
> -------------------------------------------
> If you are monitoring the same socket constantly i would
> advise you set it to async mode as well.
I assume this is a better alternative to the while(1) loop I currently
use around select. So can I set up a signal handler for each of the
sockets (there is a large number of them), and have the signal handler
run select to determine which socket has data available ?
My question about readline was whether I can use the command-line
editing library GNU readline (it gives you keyboard shorcuts and various
editing functions).
--
luc wastiaux
|
|
0
|
|
|
|
Reply
|
luc
|
5/22/2004 6:21:51 PM
|
|
luc wastiaux <dustpuppy@airpost.net> wrote:
> Viktor Lofgren wrote:
> I assume this is a better alternative to the while(1) loop I currently
> use around select. So can I set up a signal handler for each of the
> sockets (there is a large number of them), and have the signal handler
> run select to determine which socket has data available ?
If you have many sockets the async approach is not a very good idea;
if that's the case i would place them in a loop and select() them one
by one.
>
> My question about readline was whether I can use the command-line
> editing library GNU readline (it gives you keyboard shorcuts and various
> editing functions).
>
Since the readline manual does not mention not working with that setup
it should be safe to assume it does work problem-free.
|
|
0
|
|
|
|
Reply
|
Viktor
|
5/22/2004 7:37:22 PM
|
|
In article <c8nqjv014j0@news1.newsguy.com>,
luc wastiaux <dustpuppy@airpost.net> wrote:
> Hello,
> I have a program that needs to monitor different sockets for data
> available for reading. I use select for this. I would like to be able to
> type commands in the program, I figure I need to monitor STDIN as well.
> Is it possible to use the GNU readline library in conjunction with this ?
I'm not an expert on readline(), but I doubt that it can work
asynchronously like this -- I expect it doesn't return until it has read
a complete line.
I suggest you call readline() in a separate thread or process that
communicates with the main thread/process via a pipe, which the main
thread/process includes in its select(). When readline() returns, the
entire input line can be written to the pipe.
--
Barry Margolin, barmar@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
|
|
0
|
|
|
|
Reply
|
Barry
|
5/22/2004 9:17:58 PM
|
|
Barry Margolin wrote:
> In article <c8nqjv014j0@news1.newsguy.com>,
> luc wastiaux <dustpuppy@airpost.net> wrote:
>
>
>>Hello,
>>I have a program that needs to monitor different sockets for data
>>available for reading. I use select for this. I would like to be able to
>>type commands in the program, I figure I need to monitor STDIN as well.
>>Is it possible to use the GNU readline library in conjunction with this ?
>
>
> I'm not an expert on readline(), but I doubt that it can work
> asynchronously like this -- I expect it doesn't return until it has read
> a complete line.
>
> I suggest you call readline() in a separate thread or process that
> communicates with the main thread/process via a pipe, which the main
> thread/process includes in its select(). When readline() returns, the
> entire input line can be written to the pipe.
Ok this sounds like a good idea and not too hard to implement.
--
luc wastiaux
|
|
0
|
|
|
|
Reply
|
luc
|
5/23/2004 1:35:57 AM
|
|
Viktor Lofgren wrote:
> luc wastiaux <dustpuppy@airpost.net> wrote:
>
>>Viktor Lofgren wrote:
>>I assume this is a better alternative to the while(1) loop I currently
>>use around select. So can I set up a signal handler for each of the
>>sockets (there is a large number of them), and have the signal handler
>>run select to determine which socket has data available ?
>
>
> If you have many sockets the async approach is not a very good idea;
> if that's the case i would place them in a loop and select() them one
> by one.
But how do I prevent my process from taking up 99% CPU ? This is what
happens currently with the while(1) loop.
--
luc wastiaux
|
|
0
|
|
|
|
Reply
|
luc
|
5/23/2004 9:18:24 AM
|
|
luc wastiaux wrote:
>> If you have many sockets the async approach is not a very good idea;
>> if that's the case i would place them in a loop and select() them one
>> by one.
>
>
> But how do I prevent my process from taking up 99% CPU ? This is what
> happens currently with the while(1) loop.
I set a timeout value when I didn't need one. With no timeout value,
select will hang when there is no data available, which suits me fine.
Thanks for your help Viktor and Barry.
--
luc wastiaux
|
|
0
|
|
|
|
Reply
|
luc
|
5/23/2004 9:33:35 AM
|
|
luc wastiaux <dustpuppy@airpost.net> wrote:
> Viktor Lofgren wrote:
>> luc wastiaux <dustpuppy@airpost.net> wrote:
>>
>>>Viktor Lofgren wrote:
>>>I assume this is a better alternative to the while(1) loop I currently
>>>use around select. So can I set up a signal handler for each of the
>>>sockets (there is a large number of them), and have the signal handler
>>>run select to determine which socket has data available ?
>>
>>
>> If you have many sockets the async approach is not a very good idea;
>> if that's the case i would place them in a loop and select() them one
>> by one.
>
> But how do I prevent my process from taking up 99% CPU ? This is what
> happens currently with the while(1) loop.
>
>
>
Set your select timeout to 1 usecond timeout. Having 0 timeout
will eat all CPU, but having a minimal timeout won't :-)
|
|
0
|
|
|
|
Reply
|
Viktor
|
5/23/2004 12:54:05 PM
|
|
Viktor Lofgren wrote:
> luc wastiaux <dustpuppy@airpost.net> wrote:
>
>>Hello,
>>I have a program that needs to monitor different sockets for data
>>available for reading. I use select for this. I would like to be able to
>>type commands in the program, I figure I need to monitor STDIN as well.
>>Is it possible to use the GNU readline library in conjunction with this ?
>
>
> I would set STDIN in asynchronous mode instead. That will give you a signal
> when you receive input from STDIN.
>
> Something like this would do the trick
> -------------------------------------------
> if(fcntl(0, F_SETFL, O_ASYNC)<0) abort();
> if(fcntl(0, F_SETOWN, getpid())<0) abort();
> /* fcntl(0, F_SETSIG, SIGRTMIN+5); | You may want to use a realtime signal
> instead of SIGIO */
> signal(&your_sighandler, SIGIO /*SIGRTMIN+5*/)
>
> int your_sighandler(int p) {
> /* readline(...) */
> }
> -------------------------------------------
> If you are monitoring the same socket constantly i would
> advise you set it to async mode as well.
The above code only works on linux 2.6. On linux 2.4 it seems there is
no IO signal.
But above all, I need the code to work on NetBSD 1.6.1. On this system,
it seems that the signal does not get sent when there is data available
to read (I read the data from a pipe). But sending the signal manually
with 'kill -IO' makes my program read the available data. I'm puzzled
about what could be wrong.
--
luc wastiaux
|
|
0
|
|
|
|
Reply
|
luc
|
5/25/2004 5:09:42 PM
|
|
luc wastiaux wrote:
>> if(fcntl(0, F_SETFL, O_ASYNC)<0) abort();
>> if(fcntl(0, F_SETOWN, getpid())<0) abort();
>> /* fcntl(0, F_SETSIG, SIGRTMIN+5); | You may want to use a realtime
>> signal
>> instead of SIGIO */
>> signal(&your_sighandler, SIGIO /*SIGRTMIN+5*/)
>>
>> int your_sighandler(int p) {
>> /* readline(...) */
>> }
>
> But above all, I need the code to work on NetBSD 1.6.1. On this system,
> it seems that the signal does not get sent when there is data available
> to read (I read the data from a pipe). But sending the signal manually
> with 'kill -IO' makes my program read the available data. I'm puzzled
> about what could be wrong.
>
On NETBSD 1.6.1, you need to do:
fcntl(0, F_SETOWN, - getpid());
--
luc wastiaux
|
|
0
|
|
|
|
Reply
|
luc
|
5/25/2004 5:21:56 PM
|
|
luc wastiaux <dustpuppy@airpost.net> wrote:
> Viktor Lofgren wrote:
>> luc wastiaux <dustpuppy@airpost.net> wrote:
>>
>>>Hello,
>>>I have a program that needs to monitor different sockets for data
>>>available for reading. I use select for this. I would like to be able to
>>>type commands in the program, I figure I need to monitor STDIN as well.
>>>Is it possible to use the GNU readline library in conjunction with this ?
>>
>>
>> I would set STDIN in asynchronous mode instead. That will give you a signal
>> when you receive input from STDIN.
>>
>> Something like this would do the trick
>> -------------------------------------------
>> if(fcntl(0, F_SETFL, O_ASYNC)<0) abort();
>> if(fcntl(0, F_SETOWN, getpid())<0) abort();
>> /* fcntl(0, F_SETSIG, SIGRTMIN+5); | You may want to use a realtime signal
>> instead of SIGIO */
>> signal(&your_sighandler, SIGIO /*SIGRTMIN+5*/)
>>
>> int your_sighandler(int p) {
>> /* readline(...) */
>> }
>> -------------------------------------------
>> If you are monitoring the same socket constantly i would
>> advise you set it to async mode as well.
>
> The above code only works on linux 2.6. On linux 2.4 it seems there is
> no IO signal.
>
Odd, i've never experienced any trouble using SIGIO on 2.4 systems.
Are you sure you're in a sane enviorment?
--
Viktor Lofgren, Umea, Sweden
Mainly self-eductated UNIX programmer, running Slackware-current.
|
|
0
|
|
|
|
Reply
|
Viktor
|
5/25/2004 6:20:51 PM
|
|
Viktor Lofgren wrote:
> luc wastiaux <dustpuppy@airpost.net> wrote:
>
>>Viktor Lofgren wrote:
>>
>>>luc wastiaux <dustpuppy@airpost.net> wrote:
>>>
>>>
>>>>Hello,
>>>>I have a program that needs to monitor different sockets for data
>>>>available for reading. I use select for this. I would like to be able to
>>>>type commands in the program, I figure I need to monitor STDIN as well.
>>>>Is it possible to use the GNU readline library in conjunction with this ?
>>>
>>>
>>>I would set STDIN in asynchronous mode instead. That will give you a signal
>>>when you receive input from STDIN.
>>>
>>>Something like this would do the trick
>>>-------------------------------------------
>>>if(fcntl(0, F_SETFL, O_ASYNC)<0) abort();
>>>if(fcntl(0, F_SETOWN, getpid())<0) abort();
>>>/* fcntl(0, F_SETSIG, SIGRTMIN+5); | You may want to use a realtime signal
>>>instead of SIGIO */
>>>signal(&your_sighandler, SIGIO /*SIGRTMIN+5*/)
>>>
>>>int your_sighandler(int p) {
>>> /* readline(...) */
>>>}
>>>-------------------------------------------
>>>If you are monitoring the same socket constantly i would
>>>advise you set it to async mode as well.
>>
>>The above code only works on linux 2.6. On linux 2.4 it seems there is
>>no IO signal.
>>
>
>
> Odd, i've never experienced any trouble using SIGIO on 2.4 systems.
> Are you sure you're in a sane enviorment?
This code seems to work differently whether it is run on linux 2.4, 2.6
and BSD: on linux 2.4 it doesn't work, and it seems the "SIGIO" signal
doesn't exist on this system (kill -l doesn't list it). BSD requires
O_NONBLOCK also, which causes problems to linux 2.6. I find this
solution too unreliable for now, I will take a look at it again when I
have made more progress with my program.
--
luc wastiaux
|
|
0
|
|
|
|
Reply
|
luc
|
5/25/2004 11:04:18 PM
|
|
luc wastiaux <dustpuppy@airpost.net> wrote:
> Viktor Lofgren wrote:
>
>> luc wastiaux <dustpuppy@airpost.net> wrote:
>>
>>>Viktor Lofgren wrote:
>>>
>>>>luc wastiaux <dustpuppy@airpost.net> wrote:
>>>>
>>>>
>>>>>Hello,
>>>>>I have a program that needs to monitor different sockets for data
>>>>>available for reading. I use select for this. I would like to be able to
>>>>>type commands in the program, I figure I need to monitor STDIN as well.
>>>>>Is it possible to use the GNU readline library in conjunction with this ?
>>>>
>>>>
>>>>I would set STDIN in asynchronous mode instead. That will give you a signal
>>>>when you receive input from STDIN.
>>>>
>>>>Something like this would do the trick
>>>>-------------------------------------------
>>>>if(fcntl(0, F_SETFL, O_ASYNC)<0) abort();
>>>>if(fcntl(0, F_SETOWN, getpid())<0) abort();
>>>>/* fcntl(0, F_SETSIG, SIGRTMIN+5); | You may want to use a realtime signal
>>>>instead of SIGIO */
>>>>signal(&your_sighandler, SIGIO /*SIGRTMIN+5*/)
>>>>
>>>>int your_sighandler(int p) {
>>>> /* readline(...) */
>>>>}
>>>>-------------------------------------------
>>>>If you are monitoring the same socket constantly i would
>>>>advise you set it to async mode as well.
>>>
>>>The above code only works on linux 2.6. On linux 2.4 it seems there is
>>>no IO signal.
>>>
>>
>>
>> Odd, i've never experienced any trouble using SIGIO on 2.4 systems.
>> Are you sure you're in a sane enviorment?
>
> This code seems to work differently whether it is run on linux 2.4, 2.6
> and BSD: on linux 2.4 it doesn't work, and it seems the "SIGIO" signal
> doesn't exist on this system (kill -l doesn't list it). BSD requires
> O_NONBLOCK also, which causes problems to linux 2.6. I find this
> solution too unreliable for now, I will take a look at it again when I
> have made more progress with my program.
>
Your 2.4 Enviorment can not be sane, i am sitting on a 2.4 box at the
moment, and kill -l lists SIGIO perfectly fine. It is even mentioned
in signal(7).
This should take care of the Netbsd issue:
#ifdef NETBSD /* #ifndef LINUX works as well */
fcntl(fd, F_SETFL, O_NONBLOCK);
#endif
--
Viktor Lofgren, Umea, Sweden
Mainly self-eductated UNIX programmer, running Slackware-current.
|
|
0
|
|
|
|
Reply
|
Viktor
|
5/26/2004 12:52:51 AM
|
|
|
13 Replies
612 Views
(page loaded in 0.153 seconds)
|