File tree 1 file changed +88
-0
lines changed
1 file changed +88
-0
lines changed Original file line number Diff line number Diff line change
1
+ /*
2
+ * POSIX semaphores demonstration. Note especially how sem_wait() should be
3
+ * treated with regards to interruptions (like signals in this case or I/O
4
+ * delivery).
5
+ *
6
+ * Run with and without argument to see the difference.
7
+ *
8
+ * vlada@devnull.cz, 2013
9
+ */
10
+
11
+ #include <stdio.h>
12
+ #include <signal.h>
13
+ #include <pthread.h>
14
+ #include <errno.h>
15
+ #include <semaphore.h>
16
+
17
+ sem_t sem ;
18
+
19
+ #define PUTCHARF (x ) putc(x, stdout); fflush(stdout);
20
+
21
+ int
22
+ sem_wait_nointr (sem_t * sem ) {
23
+ while (sem_wait (sem ) != 0 ) {
24
+ if (errno != EINTR ) {
25
+ return (-1 );
26
+ } else {
27
+ PUTCHARF ('!' );
28
+ }
29
+ }
30
+
31
+ return (0 );
32
+ }
33
+
34
+ void *
35
+ usher (void * x )
36
+ {
37
+ while (1 ) {
38
+ sem_post (& sem );
39
+ PUTCHARF ('-' );
40
+ poll (NULL , 0 , 100 );
41
+ }
42
+ }
43
+
44
+ void
45
+ alarm_handler (int s )
46
+ {
47
+ alarm (1 );
48
+ }
49
+
50
+ int
51
+ main (int argc , char * argv [])
52
+ {
53
+ pthread_t t ;
54
+ int nointr = 0 ;
55
+ struct sigaction act ;
56
+
57
+ if (argc == 2 )
58
+ nointr = 1 ;
59
+
60
+ /* Allow to enter 5 times. */
61
+ if (sem_init (& sem , 0 , 5 ) == -1 )
62
+ err (1 , "sem_init" );
63
+
64
+ pthread_create (& t , NULL , usher , NULL );
65
+
66
+ act .sa_handler = alarm_handler ;
67
+ sigemptyset (& act .sa_mask );
68
+ act .sa_flags = 0 ;
69
+
70
+ sigaction (SIGALRM , & act , NULL );
71
+ alarm (1 );
72
+
73
+ while (1 ) {
74
+ if (nointr ) {
75
+ sem_wait_nointr (& sem );
76
+ } else {
77
+ if (sem_wait (& sem ) != 0 )
78
+ err (1 , "sem_wait" );
79
+ }
80
+ PUTCHARF ('_' );
81
+ /* Run more frequently than usher. */
82
+ poll (NULL , 0 , 10 );
83
+ }
84
+
85
+ sem_destroy (& sem );
86
+
87
+ return (0 );
88
+ }
You can’t perform that action at this time.
0 commit comments