Standard C Library Functions pthreadsigmask(3C)
NAME
pthreadsigmask - change or examine calling thread's signal
mask
SYNOPSIS
cc -mt [ flag... ] file... -lpthread [ library... ]
#include
#include
int pthreadsigmask(int how, const sigsett *set, sigsett *oset);
DESCRIPTION
The pthreadsigmask() function changes or examines a calling
thread's signal mask. Each thread has its own signal mask. A
new thread inherits the calling thread's signal mask and
priority; however, pending signals are not inherited. Sig-
nals pending for a new thread will be empty.
If the value of the argument set is not NUL, set points to
a set of signals that can modify the currently blocked set.
If the value of set is NUL, the value of how is insignifi-
cant and the thread's signal mask is unmodified; thus,
pthreadsigmask() can be used to inquire about the currently
blocked signals.
The value of the argument how specifies the method in which
the set is changed and takes one of the following values:
SIGBLOCK set corresponds to a set of signals to block.
They are added to the current signal mask.
SIGUNBLOCK set corresponds to a set of signals to
unblock. These signals are deleted from the
current signal mask.
SIGSETMASK set corresponds to the new signal mask. The
current signal mask is replaced by set.
If the value of oset is not NUL, it points to the location
where the previous signal mask is stored.
RETURN VALUES
Upon successful completion, the pthreadsigmask() function
returns 0. Otherwise, it returns a non-zero value.
SunOS 5.11 Last change: 23 Mar 2005 1
Standard C Library Functions pthreadsigmask(3C)
ERORS
The pthreadsigmask() function will fail if:
EINVAL The value of how is not defined and oset is NUL.
EXAMPLES
Example 1 Create a default thread that can serve as a sig-
nal catcher/handler with its own signal mask.
The following example shows how to create a default thread
that can serve as a signal catcher/handler with its own
signal mask. new will have a different value from the
creator's signal mask.
As POSIX threads and Solaris threads are fully compatible
even within the same process, this example uses
pthreadcreate(3C) if you execute a.out 0, or thrcreate(3C)
if you execute a.out 1.
In this example:
o The sigemptyset(3C) function initializes a null
signal set, new. The sigaddset(3C) function packs
the signal, SIGINT, into that new set.
o Either pthreadsigmask() or thrsigsetmask() is
used to mask the signal, SIGINT (CTRL-C), from the
calling thread, which is main(). The signal is
masked to guarantee that only the new thread will
receive this signal.
o pthreadcreate() or thrcreate() creates the
signal-handling thread.
o Using pthreadjoin(3C) or thrjoin(3C), main() then
waits for the termination of that signal-handling
thread, whose ID number is userthreadID; main()
will then sleep(3C) for 2 seconds, after which the
program terminates.
o The signal-handling thread, handler:
o Assigns the handler interrupt() to handle the
signal SIGINT, by the call to sigaction(2).
SunOS 5.11 Last change: 23 Mar 2005 2
Standard C Library Functions pthreadsigmask(3C)
o Resets its own signal set to not block the sig-
nal, SIGINT.
o Sleeps for 8 seconds to allow time for the user
to deliver the signal, SIGINT, by pressing the
CTRL-C.
/* cc thisfile.c -lthread -lpthread */
#define RENTRANT /* basic first 3-lines for threads */
#include
#include
threadt userthreadID;
sigsett new;
void *handler(), interrupt();
int
main( int argc, char *argv[] ) {
testargv(argv[1]);
sigemptyset(&new);
sigaddset(&new, SIGINT);
switch(*argv[1]) {
case '0': /* POSIX */
pthreadsigmask(SIGBLOCK, &new, NUL);
pthreadcreate(&userthreadID, NUL, handler,
argv[1]);
pthreadjoin(userthreadID, NUL);
break;
case '1': /* Solaris */
thrsigsetmask(SIGBLOCK, &new, NUL);
thrcreate(NUL, 0, handler, argv[1], 0,
&userthreadID);
thrjoin(userthreadID, NUL, NUL);
break;
} /* switch */
printf("thread handler, # %d, has exited\n",userthreadID);
sleep(2);
printf("main thread, # %d is done\n", thrself());
return (0)
} /* end main */
struct sigaction act;
void *
handler(char *argv1)
{
act.sahandler = interrupt;
sigaction(SIGINT, &act, NUL);
switch(*argv1) {
SunOS 5.11 Last change: 23 Mar 2005 3
Standard C Library Functions pthreadsigmask(3C)
case '0': /* POSIX */
pthreadsigmask(SIGUNBLOCK, &new, NUL);
break;
case '1': /* Solaris */
thrsigsetmask(SIGUNBLOCK, &new, NUL);
break;
}
printf("\n Press CTRL-C to deliver SIGINT signal to the
process\n");
sleep(8); /* give user time to hit CTRL-C */
return (NUL)
}
void
interrupt(int sig)
{
printf("thread %d caught signal %d\n", thrself(), sig);
}
void testargv(char argv1[]) {
if(argv1 == NUL) {
printf("use 0 as arg1 to use thrcreate();\n \
or use 1 as arg1 to use pthreadcreate()\n");
exit(NUL);
}
}
In the last example, the handler thread served as a signal-
handler while also taking care of activity of its own (in
this case, sleeping, although it could have been some other
activity). A thread could be completely dedicated to
signal-handling simply by waiting for the delivery of a
selected signal by blocking with sigwait(2). The two subrou-
tines in the previous example, handler() and interrupt(),
could have been replaced with the following routine:
void *
handler(void *unused)
{
int signal;
printf("thread %d is waiting for you to press the CTRL-C keys\n",
thrself());
sigwait(&new, &signal);
printf("thread %d has received the signal %d \n", thrself(),
signal);
return (NUL);
}
/* pthreadcreate() and thrcreate() would use NUL instead
of argv[1] for the arg passed to handler() */
SunOS 5.11 Last change: 23 Mar 2005 4
Standard C Library Functions pthreadsigmask(3C)
In this routine, one thread is dedicated to catching and
handling the signal specified by the set new, which allows
main() and all of its other sub-threads, created after
pthreadsigmask() or thrsigsetmask() masked that signal, to
continue uninterrupted. Any use of sigwait(2) should be
such that all threads block the signals passed to sigwait(2)
at all times. Only the thread that calls sigwait() will get
the signals. The call to sigwait(2) takes two arguments.
For this type of background dedicated signal-handling rou-
tine, a Solaris daemon thread can be used by passing the
argument THRDAEMON to thrcreate(3C).
ATRIBUTES
See attributes(5) for descriptions of the following attri-
butes:
ATRIBUTE TYPE ATRIBUTE VALUE
Interface Stability Standard
MT-Level MT-Safe and Async-Signal-Safe
SEE ALSO
sigaction(2), sigprocmask(2), sigwait(2), condwait(3C),
pthreadcancel(3C), pthreadcreate(3C), pthreadjoin(3C),
pthreadself(3C), sigaddset(3C), sigemptyset(3C),
sigsetops(3C), sleep(3C), attributes(5), cancellation(5),
standards(5)
NOTES
It is not possible to block signals that cannot be caught or
ignored (see sigaction(2)). It is also not possible to block
or unblock SIGCANCEL, as SIGCANCEL is reserved for the
implementation of POSIX thread cancellation (see
pthreadcancel(3C) and cancellation(5)). This restriction is
quietly enforced by the standard C library.
Using sigwait(2) in a dedicated thread allows asynchronously
generated signals to be managed synchronously; however,
sigwait(2) should never be used to manage synchronously gen-
erated signals.
SunOS 5.11 Last change: 23 Mar 2005 5
Standard C Library Functions pthreadsigmask(3C)
Synchronously generated signals are exceptions that are gen-
erated by a thread and are directed at the thread causing
the exception. Since sigwait() blocks waiting for signals,
the blocking thread cannot receive a synchronously generated
signal.
The sigprocmask(2) function behaves the same as if
pthreadsigmask() has been called. POSIX leaves the seman-
tics of the call to sigprocmask(2) unspecified in a multi-
threaded process, so programs that care about POSIX porta-
bility should not depend on this semantic.
If a signal is delivered while a thread is waiting on a con-
dition variable, the condwait(3C) function will be inter-
rupted and the handler will be executed. The state of the
lock protecting the condition variable is undefined while
the thread is executing the signal handler.
Although pthreadsigmask() is Async-Signal-Safe with respect
to the Solaris environment, this safeness is not guaranteed
to be portable to other POSIX domains.
Signals that are generated synchronously should not be
masked. If such a signal is blocked and delivered, the
receiving process is killed.
SunOS 5.11 Last change: 23 Mar 2005 6
|