[Search for users]
[Overall Top Noters]
[List of all Conferences]
[Download this site]
Title: | DECthreads Conference |
|
Moderator: | PTHRED::MARYS TE ON |
|
Created: | Mon May 14 1990 |
Last Modified: | Fri Jun 06 1997 |
Last Successful Update: | Fri Jun 06 1997 |
Number of topics: | 1553 |
Total number of notes: | 9541 |
1547.0. "thread not inheriting signal mask in DU 3.2c?" by HYDRA::BRYANT () Wed May 21 1997 13:13
Here is a reproducer from a partner which demonstrates a parent process being
killed when its child is killed. On DU 4.0, the parent process does not get
killed which I assume is the correct behavior. Is there a patch
for 3.2c that I'm just not seeing?
I killed the child process using kill(1) from another window.
parent.c
--------
#include <pthread.h>
#include <signal.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
static void *WriteToPipe(void *);
static FILE *fRead, *fWrite;
int main() {
int childPID;
int hIn, hOut;
int pWrite[2];
int pRead[2];
pthread_t threadId;
pthread_addr_t threadStatus;
if ( sigignore(SIGPIPE) != 0 )
printf("sigignore: %s\n", strerror(errno));
if ( pipe(pWrite) != 0 || pipe(pRead) != 0 )
printf("pipe: %s\n", strerror(errno));
childPID = fork();
if ( childPID == -1 )
printf("fork: %s\n", strerror(errno));
if ( childPID == 0 ) { /* Child */
close(pWrite[1]);
close(pRead[0]);
hIn = fileno(stdin);
hOut = fileno(stdout);
fclose(stdin);
fclose(stdout);
if ( dup2(pWrite[0], hIn) == -1 || dup2(pRead[1], hOut) == -1 )
printf("dup2: %s\n", strerror(errno));
if ( execl("child", "child", "", (const char*)0) == -1 )
printf("execl: %s\n", strerror(errno));
printf("Cannot start child process\n");
return 98;
} else { /* Parent */
close(pWrite[0]);
close(pRead[1]);
if ( (fWrite=fdopen(pWrite[1], "w")) == 0 ||
(fRead=fdopen(pRead[0], "r")) == 0 ) {
printf("fdopen: %s\n", strerror(errno));
return 99;
}
#if 1 /* Use thread */
pthread_create(&threadId, pthread_attr_default, WriteToPipe, 0);
pthread_join(threadId, &threadStatus);
#else /* Don't use thread */
WriteToPipe(0);
#endif
}
return 0;
}
static void *WriteToPipe(void *ignored) {
#if 0 /* sigignore in the child thread fixes the problem */
if ( sigignore(SIGPIPE) != 0 )
printf("sigignore: %s\n", strerror(errno));
#endif
printf("Parent starts writing into the pipe\n");
for ( ; ; ) {
putc('0', fWrite);
fflush(fWrite);
}
return 0;
}
child.c
--------
#include <stdio.h>
int main() {
int firstTime = 1;
fprintf(stderr, "Child has started\n");
while ( getchar() != EOF ) {
if ( firstTime ) {
fprintf(stderr, "Child is reading from the pipe\n");
fprintf(stderr, "Killing the child should not terminate the parent\n");
firstTime = 0;
}
}
}
Makefile
--------
All: parent child
parent: parent.c
cc -o parent -threads parent.c -lpthreads
child: child.c
cc -o child child.c
T.R | Title | User | Personal Name | Date | Lines |
---|
1547.1 | | DCETHD::BUTENHOF | Dave Butenhof, DECthreads | Wed May 21 1997 14:30 | 22 |
| You're misinterpreting what's happening. What you're doing (by calling
sigignore) is NOT setting the signal mask -- it's setting the signal ACTION
(to SIG_IGN).
In POSIX (and therefore in Digital UNIX 4.0), all threads share a common
process action for each signal. And therefore, all threads have SIGPIPE set
to SIG_IGN, and ignore the broken pipe. Prior to Digital UNIX 4.0, each
thread had its own private handler for the "synchronous" signal actions,
which happens to include SIGPIPE. Signal actions were not inherited. You can
work around that by having each thread call sigignore(), for example, before
doing any I/O.
I really don't know whether threads inherited the creator's signal mask in
3.2 -- when Jeff repaired the ancient OSF/1 "quirk" where all threads shared
a single (process-wide) signal mask, it didn't occur to me to ask. It didn't
really matter, since we weren't bound by any standard at the time -- and the
POSIX thread standard wasn't even final, so pretending to follow it would
have been of little value. If Jeff confirms that they did inherit the mask,
then you could convert the program to use sigprocmask instead of sigignore,
and take care of all the threads.
/dave
|