Skip to content

Commit e5a08ed

Browse files
author
Vladimir Kotal
committed
POSIX semaphore demo
1 parent 2d2d531 commit e5a08ed

File tree

1 file changed

+88
-0
lines changed

1 file changed

+88
-0
lines changed

semaphores/sem.c

+88
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
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+
}

0 commit comments

Comments
 (0)