ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Hi all,
I'm creating a small program which is going to fork off a number of children, and I need to both monitor their output and their exit status (when it occurs) from the parent half of the program. I'd like to use a signal handler for both of these tasks to minimize busy-waiting, and the documentation on sigaction seems to suggest that sa_mask can be set to handle an additional set of signals.
Can I somehow define custom signals (i.e. when one of the children writes to a pipe)? How would I go about doing this?
Can I somehow define custom signals (i.e. when one of the children writes to a pipe)? How would I go about doing this?
Just register a handler function for the SIGIO function.
Your program will recieve SIGIO signal whenever readable data becomes available on one of the open filedescriptors (e.g. an open pipe) of your program.
Sweet, you can do that on files/pipes? The man page seemed to suggest that except for sockets, SIGIO wasn't going to happen. I'll certainly try it though, it sounds promising
This is partially for a grad OS class, and we're not allowed to busy-wait (i.e. poll continuously, or even every X seconds). When nothing's being a) written or b) exiting, no CPU time can be used
When I looked at it, it was basically poll with multiple file descriptors, which means that it listens on the timeout that you give it, and then returns if one (or any) of the fd's are ready for reading. It doesn't block on the descriptors (and anyhow I wouldn't want it to)...
Originally posted by rose_bud4201 Well, as Hko said, make the pipes asynchronous with fcntl(), and then read once a SIGIO has been received. :-)
Yes, I've actualy done it successfully with a filesystem socket. And according to the man page it should work with (almost) any open file descriptor (pipe, file, tcp-socket,...).
But I agree with Martir that select() is probably a better solution, and select() is not about busy waiting.
I like to use signals simply as a wake-up call ... when a process posts some activity that another process needs to be interested in, a signal is issued simply to "make sure that the other process is awake." (Not "to wake it up.")
Meanwhile, the service-process loops continuously, removing message-elements from a queue until there are no more and only then going to sleep on the signal. It is quite likely that the process will immediately wake-up (reacting to a signal from some time ago), go through the message check one more time, find no new messages, and then go to sleep again. And to my way of thinking, "who cares?" That doesn't qualify as "busy waiting" because we will incur at-most one "extra" loop.
To my way of thinking, as long as no process loops endlessly, polling for work ("busy waiting"), it is far more important that the process does not enter an infinite or indefinite wait, than it is to worry about one extra loop now and then. The computer isn't going to be bothered if the doorbell-buzzer goes off a few more times than it has to, as long as the occupant inside is awake whenever he's supposed to be.
Even I agree to what "sundialsvcs" says... But I have one more query... what if there are more than one files opened in Asynchronous mode in a single process ? How can this case be handled, as all the files on read signal SIGIO and will be processed with a signal handler. So, how can we differentiate between these SIGIO's of different files...?
what if there are more than one files opened in Asynchronous mode in a single process ? How can this case be handled, as all the files on read signal SIGIO and will be processed with a signal handler. So, how can we differentiate between these SIGIO's of different files...?
The answer to your question in blue
There are 3 ways to do this:
Using poll(2):
Quote:
Originally Posted by man 2 poll
poll() is a variation on the theme of select(). It specifies an array of nfds structures [..] and a timeout in milliseconds.
Using select(2):
Select() is neat (IMHO), but can be difficult to use. The people who documented it, seem to have been aware of this, and made a seperate tutorial-like man page for it: man select_tut
Using SIGIO's:
Quote:
Originally Posted by man 2 fcntl
By using F_SETSIG with a non-zero value, and setting SA_SIGINFO for the signal handler (see sigaction(2)), extra information about I/O events is passed to the handler in a siginfo_t structure. If the si_code field indicates the source is SI_SIGIO, the si_fd field gives the file descriptor associated with the event. Otherwise, there is no indication which file descriptors are pending, and you should use the usual mechanisms (select(2), poll(2), read(2) with O_NONBLOCK set etc.) to determine which file descriptors are available for I/O.
[..]
Using these mechanisms, a program can implement fully asynchronous I/O without using select(2) or poll(2) most of the time.
Thanks HKO...
Can anybody help me out why this code is not working...
I am trying to communicate with named pipe in single process in Asynchromous fashion i.e. using SIGIO.. But am unable to get what the actual problem is Signal is not geting fired... Can anybody help out please....
Quote:
#include <stdio.h>
#include <fcntl.h>
#include <signal.h>
#include <unistd.h>
void *signal_handler_IO (int status); //definition of signal handler
int main()
{
int fdw1, fdr1, fdr2, fdw2;
struct sigaction saio; //definition of signal action
//named pipes are created at this path /suhas/testApps/pipe1
fdr1 = open("/suhas/testApps/pipe1", O_RDONLY | O_NONBLOCK );
if(fdr1 < 0)
perror("fdr1 failed");
fdw1 = open("/suhas/testApps/pipe1", O_WRONLY /* | O_NONBLOCK*/ );
if(fdw1 < 0)
perror("fdw1 failed");
//install the serial handler before making the device asynchronous
saio.sa_handler = signal_handler_IO;
sigemptyset(&saio.sa_mask); //saio.sa_mask = 0;
saio.sa_flags = 0;
saio.sa_restorer = NULL;
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.