1pthread_sigmask(3C) Standard C Library Functions pthread_sigmask(3C)
2
3
4
6 pthread_sigmask - change or examine calling thread's signal mask
7
9 cc -mt [ flag... ] file... -lpthread [ library... ]
10 #include <pthread.h>
11 #include <signal.h>
12
13 int pthread_sigmask(int how, const sigset_t *set, sigset_t *oset);
14
15
17 The pthread_sigmask() function changes or examines a calling thread's
18 signal mask. Each thread has its own signal mask. A new thread inherits
19 the calling thread's signal mask and priority; however, pending signals
20 are not inherited. Signals pending for a new thread will be empty.
21
22
23 If the value of the argument set is not NULL, set points to a set of
24 signals that can modify the currently blocked set. If the value of set
25 is NULL, the value of how is insignificant and the thread's signal mask
26 is unmodified; thus, pthread_sigmask() can be used to inquire about the
27 currently blocked signals.
28
29
30 The value of the argument how specifies the method in which the set is
31 changed and takes one of the following values:
32
33 SIG_BLOCK set corresponds to a set of signals to block. They are
34 added to the current signal mask.
35
36
37 SIG_UNBLOCK set corresponds to a set of signals to unblock. These
38 signals are deleted from the current signal mask.
39
40
41 SIG_SETMASK set corresponds to the new signal mask. The current sig‐
42 nal mask is replaced by set.
43
44
45
46 If the value of oset is not NULL, it points to the location where the
47 previous signal mask is stored.
48
50 Upon successful completion, the pthread_sigmask() function returns 0.
51 Otherwise, it returns a non-zero value.
52
54 The pthread_sigmask() function will fail if:
55
56 EINVAL The value of how is not defined and oset is NULL.
57
58
60 Example 1 Create a default thread that can serve as a signal
61 catcher/handler with its own signal mask.
62
63
64 The following example shows how to create a default thread that can
65 serve as a signal catcher/handler with its own signal mask. new will
66 have a different value from the creator's signal mask.
67
68
69
70 As POSIX threads and Solaris threads are fully compatible even within
71 the same process, this example uses pthread_create(3C) if you execute
72 a.out 0, or thr_create(3C) if you execute a.out 1.
73
74
75
76 In this example:
77
78
79 o The sigemptyset(3C) function initializes a null signal set,
80 new. The sigaddset(3C) function packs the signal, SIGINT,
81 into that new set.
82
83 o Either pthread_sigmask() or thr_sigsetmask() is used to mask
84 the signal, SIGINT (CTRL-C), from the calling thread, which
85 is main(). The signal is masked to guarantee that only the
86 new thread will receive this signal.
87
88 o pthread_create() or thr_create() creates the signal-handling
89 thread.
90
91 o Using pthread_join(3C) or thr_join(3C), main() then waits
92 for the termination of that signal-handling thread, whose ID
93 number is user_threadID; main() will then sleep(3C) for 2
94 seconds, after which the program terminates.
95
96 o The signal-handling thread, handler:
97
98 o Assigns the handler interrupt() to handle the signal
99 SIGINT, by the call to sigaction(2).
100
101 o Resets its own signal set to not block the signal, SIG‐
102 INT.
103
104 o Sleeps for 8 seconds to allow time for the user to
105 deliver the signal, SIGINT, by pressing the CTRL-C.
106
107 /* cc thisfile.c -lthread -lpthread */
108 #define _REENTRANT /* basic first 3-lines for threads */
109 #include <pthread.h>
110 #include <thread.h>
111 thread_t user_threadID;
112 sigset_t new;
113 void *handler(), interrupt();
114
115 int
116 main( int argc, char *argv[] ) {
117 test_argv(argv[1]);
118
119 sigemptyset(&new);
120 sigaddset(&new, SIGINT);
121 switch(*argv[1]) {
122
123 case '0': /* POSIX */
124 pthread_sigmask(SIG_BLOCK, &new, NULL);
125 pthread_create(&user_threadID, NULL, handler,
126 argv[1]);
127 pthread_join(user_threadID, NULL);
128 break;
129
130 case '1': /* Solaris */
131 thr_sigsetmask(SIG_BLOCK, &new, NULL);
132 thr_create(NULL, 0, handler, argv[1], 0,
133 &user_threadID);
134 thr_join(user_threadID, NULL, NULL);
135 break;
136 } /* switch */
137
138 printf("thread handler, # %d, has exited\n",user_threadID);
139 sleep(2);
140 printf("main thread, # %d is done\n", thr_self());
141 return (0)
142 } /* end main */
143
144 struct sigaction act;
145
146 void *
147 handler(char *argv1)
148 {
149 act.sa_handler = interrupt;
150 sigaction(SIGINT, &act, NULL);
151 switch(*argv1) {
152 case '0': /* POSIX */
153 pthread_sigmask(SIG_UNBLOCK, &new, NULL);
154 break;
155 case '1': /* Solaris */
156 thr_sigsetmask(SIG_UNBLOCK, &new, NULL);
157 break;
158 }
159 printf("\n Press CTRL-C to deliver SIGINT signal to the
160 process\n");
161 sleep(8); /* give user time to hit CTRL-C */
162 return (NULL)
163 }
164
165 void
166 interrupt(int sig)
167 {
168 printf("thread %d caught signal %d\n", thr_self(), sig);
169 }
170
171 void test_argv(char argv1[]) {
172 if(argv1 == NULL) {
173 printf("use 0 as arg1 to use thr_create();\n \
174 or use 1 as arg1 to use pthread_create()\n");
175 exit(NULL);
176 }
177 }
178
179
180
181 In the last example, the handler thread served as a signal-handler
182 while also taking care of activity of its own (in this case, sleeping,
183 although it could have been some other activity). A thread could be
184 completely dedicated to signal-handling simply by waiting for the
185 delivery of a selected signal by blocking with sigwait(2). The two sub‐
186 routines in the previous example, handler() and interrupt(), could have
187 been replaced with the following routine:
188
189
190 void *
191 handler(void *unused)
192 {
193 int signal;
194 printf("thread %d is waiting for you to press the CTRL-C keys\n",
195 thr_self());
196 sigwait(&new, &signal);
197 printf("thread %d has received the signal %d \n", thr_self(),
198 signal);
199 return (NULL);
200 }
201 /* pthread_create() and thr_create() would use NULL instead
202 of argv[1] for the arg passed to handler() */
203
204
205
206 In this routine, one thread is dedicated to catching and handling the
207 signal specified by the set new, which allows main() and all of its
208 other sub-threads, created after pthread_sigmask() or thr_sigsetmask()
209 masked that signal, to continue uninterrupted. Any use of sigwait(2)
210 should be such that all threads block the signals passed to sigwait(2)
211 at all times. Only the thread that calls sigwait() will get the sig‐
212 nals. The call to sigwait(2) takes two arguments.
213
214
215
216 For this type of background dedicated signal-handling routine, a
217 Solaris daemon thread can be used by passing the argument THR_DAEMON to
218 thr_create(3C).
219
220
222 See attributes(5) for descriptions of the following attributes:
223
224
225
226
227 ┌─────────────────────────────┬──────────────────────────────┐
228 │ ATTRIBUTE TYPE │ ATTRIBUTE VALUE │
229 ├─────────────────────────────┼──────────────────────────────┤
230 │Interface Stability │Standard │
231 ├─────────────────────────────┼──────────────────────────────┤
232 │MT-Level │MT-Safe and Async-Signal-Safe │
233 └─────────────────────────────┴──────────────────────────────┘
234
236 sigaction(2), sigprocmask(2), sigwait(2), cond_wait(3C), pthread_can‐
237 cel(3C), pthread_create(3C), pthread_join(3C), pthread_self(3C),
238 sigaddset(3C), sigemptyset(3C), sigsetops(3C), sleep(3C),
239 attributes(5), cancellation(5), standards(5)
240
242 It is not possible to block signals that cannot be caught or ignored
243 (see sigaction(2)). It is also not possible to block or unblock SIGCAN‐
244 CEL, as SIGCANCEL is reserved for the implementation of POSIX thread
245 cancellation (see pthread_cancel(3C) and cancellation(5)). This
246 restriction is quietly enforced by the standard C library.
247
248
249 Using sigwait(2) in a dedicated thread allows asynchronously generated
250 signals to be managed synchronously; however, sigwait(2) should never
251 be used to manage synchronously generated signals.
252
253
254 Synchronously generated signals are exceptions that are generated by a
255 thread and are directed at the thread causing the exception. Since sig‐
256 wait() blocks waiting for signals, the blocking thread cannot receive a
257 synchronously generated signal.
258
259
260 The sigprocmask(2) function behaves the same as if pthread_sigmask()
261 has been called. POSIX leaves the semantics of the call to sigproc‐
262 mask(2) unspecified in a multi-threaded process, so programs that care
263 about POSIX portability should not depend on this semantic.
264
265
266 If a signal is delivered while a thread is waiting on a condition vari‐
267 able, the cond_wait(3C) function will be interrupted and the handler
268 will be executed. The state of the lock protecting the condition vari‐
269 able is undefined while the thread is executing the signal handler.
270
271
272 Although pthread_sigmask() is Async-Signal-Safe with respect to the
273 Solaris environment, this safeness is not guaranteed to be portable to
274 other POSIX domains.
275
276
277 Signals that are generated synchronously should not be masked. If such
278 a signal is blocked and delivered, the receiving process is killed.
279
280
281
282SunOS 5.11 23 Mar 2005 pthread_sigmask(3C)