blob: 40634122c24b732a00fb984537cba46289471d2f [file] [log] [blame]
sewardjb48e5002002-05-13 00:16:03 +00001/********************************************************
2 * An example source module to accompany...
3 *
4 * "Using POSIX Threads: Programming with Pthreads"
5 * by Brad nichols, Dick Buttlar, Jackie Farrell
6 * O'Reilly & Associates, Inc.
7 *
8 ********************************************************
9 * sig.c
10 *
11 * Simple example of pthreads and signals.
12 */
13
14#include <stdlib.h>
15#include <stdio.h>
16#include <unistd.h>
17#include <signal.h>
18#include <sys/types.h>
19
20#include <pthread.h>
21
22#define MAX_NUM_THREADS 10
23
24
25void *catch_usr1(void *p)
26{
27 int signo=SIGUSR1;
28 /* struct sigaction action; */
29 int caught;
30 sigset_t sigs_to_catch;
31
32 /* Identify our thread */
33 printf("\ncatchit() signal %d processing running as thread 0x%x \n",
34 signo, (int)pthread_self());
35 printf("Someone please send pid %d a SIGUSR1\n", getpid());
36
37 /*
38 * We inherited a thread sigmask with all the signals
39 * blocked. So, we can wait on whatever signals we're
40 * interested in and (as long as no other thread waits
41 * for them) we'll be sure return from sigwait() to
42 * handle it.
43 */
44
45 /* set this thread's signal mask to block out all other signals */
46 sigemptyset(&sigs_to_catch);
47 sigaddset(&sigs_to_catch, signo);
48
49 sigwait(&sigs_to_catch, &caught);
50
51 printf("\ncatchit() signal %d processing thread caught signal %d\n",
52 signo, caught);
53
54 return(NULL);
55}
56
57void bugcatcher(int sig)
58{
59 printf("The BUGCATCHER caught signal %d in thread 0x%x\n",
60 sig, (int)pthread_self());
61 pthread_exit(0);
62}
63
64void *cause_sig_sync(void *p)
65{
66 int i, id;
67 sigset_t sigs_to_catch;
68
69 /* Identify our thread */
70 printf("cause_sig_sync() running in thread 0x%x\n", (int)pthread_self());
71
72 /* set this thread's signal mask to block out all other signals */
73 sigemptyset(&sigs_to_catch);
74 sigaddset(&sigs_to_catch, SIGSEGV);
75 sigaddset(&sigs_to_catch, SIGBUS);
76 pthread_sigmask(SIG_UNBLOCK, &sigs_to_catch, NULL);
77
78 /* Loop simulating useful processing in this thread */
79 for(i=1;i==i;i++) {
80 printf("printing count: %4d\r",i);
81 if (i%100 == 0) {
82 id = *(int *)p; /* Guaranteed bad address */
83 }
84 }
85
86 return(NULL);
87}
88
89extern int
90main(void)
91{
92 int i;
93 pthread_t threads[MAX_NUM_THREADS];
94 int num_threads = 0;
95 sigset_t sigs_to_block;
96 struct sigaction action;
97
98
99 /* Identify our thread */
100 printf("main() running in thread 0x%x\n", (int)pthread_self());
101
102 /*
103 * Set this thread's signal mask to block out all other signals
104 * Other threads will inherit the mask
105 */
106 sigfillset(&sigs_to_block);
107 pthread_sigmask(SIG_BLOCK, &sigs_to_block, NULL);
108
109 /* Set signal handler for catching SIGSEGV and SIGBUS */
110 action.sa_handler=bugcatcher;
111 sigaction(SIGSEGV, &action, NULL);
112 sigaction(SIGBUS, &action, NULL);
113
114 /* spawn the threads */
115
116 /* Make sure we can catch synchronous signals as exceptions */
117 pthread_create(&threads[num_threads++],
118 NULL,
119 cause_sig_sync,
120 NULL);
121
122 /* Rather than install the action/handler for the process,
123 we create a thread to wait for the signal */
124 pthread_create(&threads[num_threads++],
125 NULL,
126 catch_usr1,
127 NULL);
128
129 printf("main()\t\t\t\t%d threads created\n",num_threads);
130
131 /* wait until all threads have finished */
132 for (i = 0; i < num_threads; i++) {
133 pthread_join(threads[i], NULL);
134 printf("main()\t\tjoined to thread %d \n", i);
135 }
136
137 printf("main()\t\tall %d threads have finished. \n", num_threads);
138
139 return 0;
140}
141