LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 09-11-2005, 02:44 PM   #1
rose_bud4201
Member
 
Registered: Aug 2002
Location: St Louis, MO
Distribution: Xubuntu, RHEL, Solaris 10
Posts: 929

Rep: Reputation: 30
sigaction() - how to create custom signals?


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?

Thanks!
 
Old 09-11-2005, 03:19 PM   #2
Matir
LQ Guru
 
Registered: Nov 2004
Location: San Jose, CA
Distribution: Debian, Arch
Posts: 8,507

Rep: Reputation: 128Reputation: 128
SIGUSR1 and SIGUSR2 are reserved for user-defined (really program-defined) actions. See man 7 signal for a full list of signals.
 
Old 09-11-2005, 04:50 PM   #3
Hko
Senior Member
 
Registered: Aug 2002
Location: Groningen, The Netherlands
Distribution: Debian
Posts: 2,536

Rep: Reputation: 111Reputation: 111
Quote:
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.
 
Old 09-11-2005, 10:59 PM   #4
rose_bud4201
Member
 
Registered: Aug 2002
Location: St Louis, MO
Distribution: Xubuntu, RHEL, Solaris 10
Posts: 929

Original Poster
Rep: Reputation: 30
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
 
Old 09-11-2005, 11:08 PM   #5
Matir
LQ Guru
 
Registered: Nov 2004
Location: San Jose, CA
Distribution: Debian, Arch
Posts: 8,507

Rep: Reputation: 128Reputation: 128
Although, out of curiousity, and perhaps I don't understand your intent, why don't you just use select()?
 
Old 09-11-2005, 11:29 PM   #6
rose_bud4201
Member
 
Registered: Aug 2002
Location: St Louis, MO
Distribution: Xubuntu, RHEL, Solaris 10
Posts: 929

Original Poster
Rep: Reputation: 30
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
 
Old 09-11-2005, 11:32 PM   #7
Matir
LQ Guru
 
Registered: Nov 2004
Location: San Jose, CA
Distribution: Debian, Arch
Posts: 8,507

Rep: Reputation: 128Reputation: 128
select() does not busy wait... it basically handles listening for signals from multiple fds for you, as I understand it.
 
Old 09-11-2005, 11:37 PM   #8
rose_bud4201
Member
 
Registered: Aug 2002
Location: St Louis, MO
Distribution: Xubuntu, RHEL, Solaris 10
Posts: 929

Original Poster
Rep: Reputation: 30
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)...
 
Old 09-11-2005, 11:38 PM   #9
Matir
LQ Guru
 
Registered: Nov 2004
Location: San Jose, CA
Distribution: Debian, Arch
Posts: 8,507

Rep: Reputation: 128Reputation: 128
You don't want it to block? Then how will you avoid busywaiting?
 
Old 09-12-2005, 08:23 AM   #10
rose_bud4201
Member
 
Registered: Aug 2002
Location: St Louis, MO
Distribution: Xubuntu, RHEL, Solaris 10
Posts: 929

Original Poster
Rep: Reputation: 30
Well, as Hko said, make the pipes asynchronous with fcntl(), and then read once a SIGIO has been received. :-)
 
Old 09-12-2005, 11:08 AM   #11
Hko
Senior Member
 
Registered: Aug 2002
Location: Groningen, The Netherlands
Distribution: Debian
Posts: 2,536

Rep: Reputation: 111Reputation: 111
Quote:
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.
 
Old 09-12-2005, 12:41 PM   #12
sundialsvcs
LQ Guru
 
Registered: Feb 2004
Location: SE Tennessee, USA
Distribution: Gentoo, LFS
Posts: 10,659
Blog Entries: 4

Rep: Reputation: 3940Reputation: 3940Reputation: 3940Reputation: 3940Reputation: 3940Reputation: 3940Reputation: 3940Reputation: 3940Reputation: 3940Reputation: 3940Reputation: 3940
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.
 
Old 05-18-2006, 07:53 AM   #13
TechieSuhas
LQ Newbie
 
Registered: May 2006
Posts: 2

Rep: Reputation: 0
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...?
 
Old 05-18-2006, 08:17 AM   #14
Hko
Senior Member
 
Registered: Aug 2002
Location: Groningen, The Netherlands
Distribution: Debian
Posts: 2,536

Rep: Reputation: 111Reputation: 111
Quote:
Originally Posted by TechieSuhas
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:
  1. 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.
  2. 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
  3. 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.

Last edited by Hko; 05-18-2006 at 08:21 AM.
 
Old 05-23-2006, 02:21 AM   #15
TechieSuhas
LQ Newbie
 
Registered: May 2006
Posts: 2

Rep: Reputation: 0
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;

if(0 > sigaction(SIGIO, &saio, NULL))
perror("Error SigAction");

if(0 > fcntl(fdr1, F_SETOWN, getpid()))
perror("fcntl Error fdr1 pos1");
fcntl(fdr1, F_SETFL, FASYNC);

printf("Data written on pipe fdw1 = %d", write(fdw1, "abc", 3));
printf("After write\n");

while(1); //just to check if the signal is fired instead of terminating the application
close(fdw1);
close(fdr1);
}

void *signal_handler_IO (int status)
{
printf("*********** received SIGIO signal. ***********\n");
return NULL;
}
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
DISCUSSION: Create your own custom Live Linux CD mchirico LinuxAnswers Discussion 3 05-16-2019 05:48 PM
How to create a custom desktop in linux playtime Linux From Scratch 6 11-07-2005 01:44 PM
Create custom CD crimsontide Debian 1 07-21-2005 02:40 PM
how to create a custom installer? bonzai-panthera Linux From Scratch 0 01-19-2004 04:04 AM
create custom log pravash Linux - General 2 10-03-2003 01:48 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 08:48 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration