Last active
December 18, 2023 02:57
-
-
Save mu578/1bd0ce282a425b9947b87334545086fc to your computer and use it in GitHub Desktop.
ping pong posix semaphore
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// cc -pedantic -Wno-newline-eof -std=c99 ping.c -o ping_server.cmd | |
// cc -pedantic -Wno-newline-eof -std=c99 pong.c -o pong_client.cmd | |
// >$ ./ping_server.cmd & ./pong_client.cmd | |
// cc -pedantic -Wno-newline-eof -std=c99 ping_pong.c -o pong_ping.cmd | |
// >$ ./pong_ping.cmd | |
// cc -pedantic -Wno-newline-eof -std=c99 ping_pong_macos_gcd.c -o ping_pong_2.cmd | |
// >$ ./ping_pong_2.cmd | |
// cc -pedantic -Wno-newline-eof -std=c99 ping_pong_macos_gcd2.c -o ping_pong_3.cmd | |
// >$ ./ping_pong_3.cmd | |
------------------------------------------------------------------------------------------------------------------------ | |
// ping.c | |
#include <sys/stat.h> | |
#include <semaphore.h> | |
#include <unistd.h> | |
int main(int argc, const char * argv[]) | |
{ | |
size_t i = 0; | |
sem_t * ping, * pong; | |
(void)argc; | |
(void)argv; | |
if (SEM_FAILED == (ping = sem_open("/ping", O_CREAT, 0644, 1))) { | |
return -1; | |
} | |
if (SEM_FAILED == (pong = sem_open("/pong", O_CREAT, 0644, 0))) { | |
sem_close(ping); | |
sem_unlink("/ping"); | |
return -1; | |
} | |
for (; i < 10; i++) { | |
write(STDERR_FILENO, "ping\n", 5); | |
sem_post(pong); | |
sleep(1); | |
sem_wait(ping); | |
} | |
sem_close(pong); | |
sem_close(ping); | |
sem_unlink("/ping"); | |
sem_unlink("/pong"); | |
return 0; | |
} | |
/* EOF */ | |
------------------------------------------------------------------------------------------------------------------------ | |
// pong.c | |
#include <sys/stat.h> | |
#include <semaphore.h> | |
#include <unistd.h> | |
int main(int argc, const char * argv[]) | |
{ | |
size_t i = 0; | |
sem_t * ping, * pong; | |
(void)argc; | |
(void)argv; | |
if (SEM_FAILED == (ping = sem_open("/ping", O_CREAT, 0644, 1))) { | |
return -1; | |
} | |
if (SEM_FAILED == (pong = sem_open("/pong", O_CREAT, 0644, 0))) { | |
sem_close(ping); | |
return -1; | |
} | |
for (; i < 10; i++) { | |
sem_wait(pong); | |
write(STDERR_FILENO, "pong\n", 5); | |
sem_post(ping); | |
} | |
sem_close(pong); | |
sem_close(ping); | |
return 0; | |
} | |
/* EOF */ | |
------------------------------------------------------------------------------------------------------------------------ | |
// ping_pong.c | |
#include <sys/stat.h> | |
#include <fcntl.h> | |
#include <semaphore.h> | |
#include <unistd.h> | |
#include <stdlib.h> | |
#include <pthread.h> | |
struct thr_cookie | |
{ | |
sem_t * u_ping; | |
sem_t * u_pong; | |
}; | |
void * ping(void * arg) | |
{ | |
sem_t * ping = ((struct thr_cookie *)arg)->u_ping; | |
sem_t * pong = ((struct thr_cookie *)arg)->u_pong; | |
sem_unlink("/ping"); | |
sem_unlink("/pong"); | |
if (SEM_FAILED == (ping = sem_open("/ping", O_CREAT, 0644, 1))) { | |
return NULL; | |
} | |
if (SEM_FAILED == (pong = sem_open("/pong", O_CREAT, 0644, 0))) { | |
sem_close(ping); | |
sem_unlink("/ping"); | |
return NULL; | |
} | |
do { | |
write(STDOUT_FILENO, "ping\n", 5); | |
sem_post(pong); | |
sleep(1); | |
sem_wait(ping); | |
} while (1); | |
return NULL; | |
} | |
void * pong(void * arg) | |
{ | |
sem_t * ping = ((struct thr_cookie *)arg)->u_ping; | |
sem_t * pong = ((struct thr_cookie *)arg)->u_pong; | |
if (SEM_FAILED == (ping = sem_open("/ping", O_CREAT, 0644, 1))) { | |
return NULL; | |
} | |
if (SEM_FAILED == (pong = sem_open("/pong", O_CREAT, 0644, 0))) { | |
sem_close(ping); | |
return NULL; | |
} | |
do { | |
sem_wait(pong); | |
write(STDOUT_FILENO, "pong\n", 5); | |
sem_post(ping); | |
} while (1); | |
return NULL; | |
} | |
int main(int argc, const char * argv[]) | |
{ | |
pthread_t thr_ping, thr_pong; | |
struct thr_cookie * cookie = calloc(1, sizeof(struct thr_cookie)); | |
(void)argc; | |
(void)argv; | |
pthread_create(&thr_ping, NULL, ping, cookie); | |
pthread_create(&thr_pong, NULL, pong, cookie); | |
pthread_join(thr_ping, NULL); | |
pthread_join(thr_pong, NULL); | |
free(cookie); | |
return 0; | |
} | |
/* EOF */ | |
------------------------------------------------------------------------------------------------------------------------ | |
// ping_pong_macos_gcd.c | |
#include <sys/stat.h> | |
#include <fcntl.h> | |
# if __APPLE__ && __MACH__ | |
# include <dispatch/dispatch.h> | |
# else | |
# include <semaphore.h> | |
# endif | |
#include <unistd.h> | |
#include <stdlib.h> | |
#include <pthread.h> | |
struct thr_cookie | |
{ | |
# if __APPLE__ && __MACH__ | |
dispatch_semaphore_t u_ping; | |
dispatch_semaphore_t u_pong; | |
# else | |
sem_t u_ping; | |
sem_t u_pong; | |
# endif | |
}; | |
void * ping(void * arg) | |
{ | |
# if __APPLE__ && __MACH__ | |
dispatch_semaphore_t ping = ((struct thr_cookie *)arg)->u_ping; | |
dispatch_semaphore_t pong = ((struct thr_cookie *)arg)->u_pong; | |
# else | |
sem_t ping = ((struct thr_cookie *)arg)->u_ping; | |
sem_t pong = ((struct thr_cookie *)arg)->u_pong; | |
# endif | |
int c = 5; | |
while (c-- > 0) { | |
# if __APPLE__ && __MACH__ | |
dispatch_semaphore_wait(ping, DISPATCH_TIME_FOREVER); | |
# else | |
sem_wait(&ping); | |
# endif | |
write(STDOUT_FILENO, "ping\n", 5); | |
# if __APPLE__ && __MACH__ | |
dispatch_semaphore_signal(pong); | |
# else | |
sem_post(&pong); | |
# endif | |
} | |
return NULL; | |
} | |
void * pong(void * arg) | |
{ | |
# if __APPLE__ && __MACH__ | |
dispatch_semaphore_t ping = ((struct thr_cookie *)arg)->u_ping; | |
dispatch_semaphore_t pong = ((struct thr_cookie *)arg)->u_pong; | |
# else | |
sem_t ping = ((struct thr_cookie *)arg)->u_ping; | |
sem_t pong = ((struct thr_cookie *)arg)->u_pong; | |
# endif | |
int c = 5; | |
while (c-- > 0) { | |
# if __APPLE__ && __MACH__ | |
dispatch_semaphore_wait(pong, DISPATCH_TIME_FOREVER); | |
# else | |
sem_wait(&pong); | |
# endif | |
write(STDOUT_FILENO, "pong\n", 5); | |
# if __APPLE__ && __MACH__ | |
dispatch_semaphore_signal(ping); | |
# else | |
sem_post(&ping); | |
# endif | |
} | |
return NULL; | |
} | |
int main(int argc, const char * argv[]) | |
{ | |
pthread_t thr_ping, thr_pong; | |
struct thr_cookie * cookie = calloc(1, sizeof(struct thr_cookie)); | |
(void)argc; | |
(void)argv; | |
# if __APPLE__ && __MACH__ | |
cookie->u_ping = dispatch_semaphore_create(1); | |
cookie->u_pong = dispatch_semaphore_create(0); | |
# else | |
sem_init(&cookie->u_ping, 0, 1); | |
sem_init(&cookie->u_pong, 0, 0); | |
# endif | |
pthread_create(&thr_ping, NULL, ping, cookie); | |
pthread_create(&thr_pong, NULL, pong, cookie); | |
pthread_join(thr_ping, NULL); | |
pthread_join(thr_pong, NULL); | |
# if __APPLE__ && __MACH__ | |
dispatch_release(cookie->u_ping); | |
dispatch_release(cookie->u_pong); | |
# else | |
sem_destroy(&cookie->u_ping); | |
sem_destroy(&cookie->u_pong); | |
# endif | |
free(cookie); | |
return 0; | |
} | |
/* EOF */ | |
------------------------------------------------------------------------------------------------------------------------ | |
// ping_pong_macos_gcd2.c | |
#include <sys/stat.h> | |
#include <fcntl.h> | |
# if __APPLE__ && __MACH__ | |
# include <dispatch/dispatch.h> | |
# else | |
# include <semaphore.h> | |
# endif | |
#include <unistd.h> | |
#include <stdlib.h> | |
#include <pthread.h> | |
struct xsem | |
{ | |
# if __APPLE__ && __MACH__ | |
dispatch_semaphore_t u_sem; | |
# else | |
sem_t u_sem; | |
# endif | |
}; | |
typedef struct xsem xsem_t; | |
static inline | |
long xsem_init(xsem_t * sem, unsigned int value) | |
{ | |
# if __APPLE__ && __MACH__ | |
sem->u_sem = dispatch_semaphore_create(value); | |
return 0; | |
# else | |
return sem_init(&sem->u_sem, 0, value); | |
# endif | |
} | |
static inline | |
long xsem_wait(xsem_t * sem) | |
{ | |
long ret = -1; | |
# if __APPLE__ && __MACH__ | |
ret = dispatch_semaphore_wait(sem->u_sem, DISPATCH_TIME_FOREVER) != 0 ? -1 : 0; | |
# else | |
do { | |
ret = sem_wait(&s->sem); | |
} while (ret == -1 && errno == EINTR); | |
# endif | |
return ret; | |
} | |
static inline | |
long xsem_trywait(xsem_t * sem) | |
{ | |
# if __APPLE__ && __MACH__ | |
return dispatch_semaphore_wait(sem->u_sem, DISPATCH_TIME_NOW) != 0 ? -1 : 0; | |
# else | |
return sem_trywait(&sem->u_sem); | |
# endif | |
} | |
static inline | |
long xsem_post(xsem_t * sem) | |
{ | |
# if __APPLE__ && __MACH__ | |
dispatch_semaphore_signal(sem->u_sem); | |
return 0; | |
# else | |
return sem_post(&sem->u_sem); | |
# endif | |
} | |
static inline | |
void xsem_destroy(xsem_t * sem) | |
{ | |
# if __APPLE__ && __MACH__ | |
dispatch_release(sem->u_sem); | |
# else | |
sem_destroy(&sem->u_sem); | |
# endif | |
} | |
struct thr_cookie | |
{ | |
xsem_t u_ping; | |
xsem_t u_pong; | |
}; | |
void * ping(void * arg) | |
{ | |
xsem_t ping = ((struct thr_cookie *)arg)->u_ping; | |
xsem_t pong = ((struct thr_cookie *)arg)->u_pong; | |
int c = 5; | |
while (c-- > 0) { | |
xsem_wait(&ping); | |
write(STDOUT_FILENO, "ping\n", 5); | |
sleep(1); | |
xsem_post(&pong); | |
} | |
return NULL; | |
} | |
void * pong(void * arg) | |
{ | |
xsem_t ping = ((struct thr_cookie *)arg)->u_ping; | |
xsem_t pong = ((struct thr_cookie *)arg)->u_pong; | |
int c = 5; | |
while (c-- > 0) { | |
xsem_wait(&pong); | |
write(STDOUT_FILENO, "pong\n", 5); | |
xsem_post(&ping); | |
} | |
return NULL; | |
} | |
int main(int argc, const char * argv[]) | |
{ | |
pthread_t thr_ping, thr_pong; | |
struct thr_cookie * cookie = calloc(1, sizeof(struct thr_cookie)); | |
(void)argc; | |
(void)argv; | |
xsem_init(&cookie->u_ping, 1); | |
xsem_init(&cookie->u_pong, 0); | |
pthread_create(&thr_ping, NULL, ping, cookie); | |
pthread_create(&thr_pong, NULL, pong, cookie); | |
pthread_join(thr_ping, NULL); | |
pthread_join(thr_pong, NULL); | |
xsem_destroy(&cookie->u_ping); | |
xsem_destroy(&cookie->u_pong); | |
free(cookie); | |
return 0; | |
} | |
/* EOF */ | |
------------------------------------------------------------------------------------------------------------------------ | |
// ping_pong_pshared_emulation_draf.c | |
#include <sys/stat.h> | |
#include <sys/mman.h> | |
#include <fcntl.h> | |
# if __APPLE__ && __MACH__ | |
# include <dispatch/dispatch.h> | |
# endif | |
#include <semaphore.h> | |
#include <unistd.h> | |
#include <string.h> | |
#include <stdlib.h> | |
#include <stdio.h> | |
#include <limits.h> | |
#include <errno.h> | |
#include <pthread.h> | |
struct xsem | |
{ | |
char u_sid[24]; | |
int u_isp; | |
# if __APPLE__ && __MACH__ | |
dispatch_semaphore_t u_sem; | |
sem_t * u_shr; | |
# else | |
sem_t u_sem; | |
# endif | |
}; | |
typedef struct xsem xsem_t; | |
static inline | |
long xsem_init(xsem_t * sem, int pshared, unsigned int value) | |
{ | |
int ret = -1; | |
# if __APPLE__ && __MACH__ | |
if (pshared) { | |
memset(sem->u_sid, 0, sizeof(char) * 24); | |
memcpy(sem->u_sid, "/tmp/semXXXXXXXXXXXXXXX", sizeof(char) * (24 - 1)); | |
close(mkstemp(sem->u_sid)); | |
unlink(sem->u_sid); | |
sem->u_shr = sem_open(sem->u_sid + 4, O_CREAT, O_RDWR, value); | |
if (SEM_FAILED != sem->u_shr) { | |
sem->u_isp = 1; | |
sem = mmap(sem->u_shr, sizeof(struct xsem), PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0); | |
ret = 0; | |
} else { | |
sem->u_isp = 0; | |
ret = -1; | |
} | |
} else { | |
sem->u_isp = 0; | |
sem->u_sem = dispatch_semaphore_create(value); | |
ret = 0; | |
} | |
# else | |
if (pshared) { | |
sem->u_isp = 1; | |
ret = sem_init(&sem->u_sem, 1, value); | |
if (0 == ret) { | |
sem->u_isp = 1; | |
sem = mmap(NULL, sizeof(struct xsem), PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0); | |
} else { | |
sem->u_isp = 0; | |
} | |
} else { | |
sem->u_isp = 0; | |
ret = sem_init(&sem->u_sem, 0, value); | |
} | |
# endif | |
return ret; | |
} | |
static inline | |
long xsem_wait(xsem_t * sem) | |
{ | |
long ret = -1; | |
# if __APPLE__ && __MACH__ | |
if (sem->u_isp) { | |
do { | |
ret = sem_wait(sem->u_shr); | |
} while (ret == -1 && errno == EINTR); | |
} else { | |
ret = dispatch_semaphore_wait(sem->u_sem, DISPATCH_TIME_FOREVER) != 0 ? -1 : 0; | |
} | |
# else | |
do { | |
ret = sem_wait(&sem->u_sem); | |
} while (ret == -1 && errno == EINTR); | |
# endif | |
return ret; | |
} | |
static inline | |
long xsem_trywait(xsem_t * sem) | |
{ | |
# if __APPLE__ && __MACH__ | |
if (sem->u_isp) { | |
return sem_trywait(sem->u_shr); | |
} | |
return dispatch_semaphore_wait(sem->u_sem, DISPATCH_TIME_NOW) != 0 ? -1 : 0; | |
# else | |
return sem_trywait(&sem->u_sem); | |
# endif | |
} | |
static inline | |
long xsem_post(xsem_t * sem) | |
{ | |
# if __APPLE__ && __MACH__ | |
if (sem->u_isp) { | |
return sem_post(sem->u_shr); | |
} | |
dispatch_semaphore_signal(sem->u_sem); | |
return 0; | |
# else | |
return sem_post(&sem->u_sem); | |
# endif | |
} | |
static inline | |
void xsem_destroy(xsem_t * sem) | |
{ | |
# if __APPLE__ && __MACH__ | |
if (sem->u_isp) { | |
sem_close(sem->u_shr); | |
sem_unlink(sem->u_sid + 4); | |
munmap(sem, sizeof(struct xsem)); | |
} else { | |
dispatch_release(sem->u_sem); | |
} | |
# else | |
sem_destroy(&sem->u_sem); | |
if (sem->u_isp) { | |
munmap(sem, sizeof(struct xsem)); | |
} | |
# endif | |
sem = NULL; | |
} | |
struct thr_cookie | |
{ | |
xsem_t u_ping; | |
xsem_t u_pong; | |
}; | |
void * ping(void * arg) | |
{ | |
xsem_t ping = ((struct thr_cookie *)arg)->u_ping; | |
xsem_t pong = ((struct thr_cookie *)arg)->u_pong; | |
int c = 5; | |
do { | |
xsem_wait(&ping); | |
write(STDOUT_FILENO, "ping\n", 5); | |
sleep(1); | |
xsem_post(&pong); | |
} while (c-- > 0); | |
return NULL; | |
} | |
void * pong(void * arg) | |
{ | |
xsem_t ping = ((struct thr_cookie *)arg)->u_ping; | |
xsem_t pong = ((struct thr_cookie *)arg)->u_pong; | |
int c = 5; | |
do { | |
xsem_wait(&pong); | |
write(STDOUT_FILENO, "pong\n", 5); | |
xsem_post(&ping); | |
} while (c-- > 0); | |
return NULL; | |
} | |
int main(int argc, const char * argv[]) | |
{ | |
pthread_t thr_ping, thr_pong; | |
struct thr_cookie * cookie = calloc(1, sizeof(struct thr_cookie)); | |
(void)argc; | |
(void)argv; | |
xsem_init(&cookie->u_ping, 1, 1); | |
xsem_init(&cookie->u_pong, 1, 0); | |
pthread_create(&thr_ping, NULL, ping, cookie); | |
pthread_create(&thr_pong, NULL, pong, cookie); | |
pthread_join(thr_ping, NULL); | |
pthread_join(thr_pong, NULL); | |
xsem_destroy(&cookie->u_ping); | |
xsem_destroy(&cookie->u_pong); | |
free(cookie); | |
return 0; | |
} | |
/* EOF */ | |
------------------------------------------------------------------------------------------------------------------------ | |
// ping_pong_pshared_test.c | |
#include <sys/stat.h> | |
#include <sys/mman.h> | |
#include <fcntl.h> | |
#include <dispatch/dispatch.h> | |
#include <semaphore.h> | |
#include <unistd.h> | |
#include <string.h> | |
#include <stdlib.h> | |
#include <stdio.h> | |
#include <limits.h> | |
#include <errno.h> | |
#include <pthread.h> | |
struct xsem | |
{ | |
char u_sid[24]; | |
int u_isp; | |
# if __APPLE__ && __MACH__ | |
dispatch_semaphore_t u_sem; | |
sem_t * u_shr; | |
# else | |
sem_t u_sem; | |
# endif | |
}; | |
typedef struct xsem * xsem_t; | |
static inline | |
long xsem_init(xsem_t * sem, int pshared, unsigned int value) | |
{ | |
int ret = -1; | |
# if __APPLE__ && __MACH__ | |
if (pshared) { | |
*sem = mmap(NULL, sizeof(struct xsem), PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0); | |
memset((*sem)->u_sid, 0, sizeof(char) * 24); | |
memcpy((*sem)->u_sid, "/tmp/semXXXXXXXXXXXXXXX", sizeof(char) * (24 - 1)); | |
close(mkstemp((*sem)->u_sid)); | |
unlink((*sem)->u_sid); | |
(*sem)->u_shr = sem_open((*sem)->u_sid + 4, O_CREAT, O_RDWR, value); | |
if (SEM_FAILED != (*sem)->u_shr) { | |
(*sem)->u_isp = 1; | |
ret = 0; | |
} else { | |
(*sem)->u_isp = 0; | |
munmap(*sem, sizeof(struct xsem)); | |
ret = -1; | |
} | |
} else { | |
(*sem)->u_isp = 0; | |
(*sem)->u_sem = dispatch_semaphore_create(value); | |
ret = 0; | |
} | |
# else | |
if (pshared) { | |
*sem = mmap(NULL, sizeof(struct xsem), PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0); | |
ret = sem_init(&(*sem)->u_sem, 1, value); | |
if (0 == ret) { | |
(*sem)->u_isp = 1; | |
} else { | |
(*sem)->u_isp = 0; | |
munmap(*sem, sizeof(struct xsem)); | |
ret = -1; | |
} | |
} else { | |
ret = sem_init(&(*sem)->u_sem, 0, value); | |
(*sem)->u_isp = 0; | |
} | |
# endif | |
return ret; | |
} | |
static inline | |
long xsem_wait(xsem_t * sem) | |
{ | |
long ret = -1; | |
# if __APPLE__ && __MACH__ | |
if ((*sem)->u_isp) { | |
do { | |
ret = sem_wait((*sem)->u_shr); | |
} while (ret == -1 && errno == EINTR); | |
} else { | |
ret = dispatch_semaphore_wait((*sem)->u_sem, DISPATCH_TIME_FOREVER) != 0 ? -1 : 0; | |
} | |
# else | |
do { | |
ret = sem_wait(&(*sem)->u_sem); | |
} while (ret == -1 && errno == EINTR); | |
# endif | |
return ret; | |
} | |
static inline | |
long xsem_trywait(xsem_t * sem) | |
{ | |
# if __APPLE__ && __MACH__ | |
if ((*sem)->u_isp) { | |
return sem_trywait((*sem)->u_shr); | |
} | |
return dispatch_semaphore_wait((*sem)->u_sem, DISPATCH_TIME_NOW) != 0 ? -1 : 0; | |
# else | |
return sem_trywait(&(*sem)->u_sem); | |
# endif | |
} | |
static inline | |
long xsem_post(xsem_t * sem) | |
{ | |
# if __APPLE__ && __MACH__ | |
if ((*sem)->u_isp) { | |
return sem_post((*sem)->u_shr); | |
} | |
dispatch_semaphore_signal((*sem)->u_sem); | |
return 0; | |
# else | |
return sem_post(&(*sem)->u_sem); | |
# endif | |
} | |
static inline | |
void xsem_destroy(xsem_t * sem) | |
{ | |
# if __APPLE__ && __MACH__ | |
if ((*sem)->u_isp) { | |
sem_close((*sem)->u_shr); | |
sem_unlink((*sem)->u_sid + 4); | |
munmap(*sem, sizeof(struct xsem)); | |
} else { | |
dispatch_release((*sem)->u_sem); | |
} | |
# else | |
sem_destroy(&(*sem)->u_sem); | |
if ((*sem)->u_isp) { | |
munmap(sem, sizeof(struct xsem)); | |
} | |
# endif | |
sem = NULL; | |
} | |
struct thr_cookie | |
{ | |
xsem_t u_ping; | |
xsem_t u_pong; | |
}; | |
void * ping(void * arg) | |
{ | |
xsem_t ping = ((struct thr_cookie *)arg)->u_ping; | |
xsem_t pong = ((struct thr_cookie *)arg)->u_pong; | |
int c = 5; | |
do { | |
xsem_wait(&ping); | |
write(STDOUT_FILENO, "ping\n", 5); | |
sleep(1); | |
xsem_post(&pong); | |
} while (c-- > 0); | |
return NULL; | |
} | |
void * pong(void * arg) | |
{ | |
xsem_t ping = ((struct thr_cookie *)arg)->u_ping; | |
xsem_t pong = ((struct thr_cookie *)arg)->u_pong; | |
int c = 5; | |
do { | |
xsem_wait(&pong); | |
write(STDOUT_FILENO, "pong\n", 5); | |
xsem_post(&ping); | |
} while (c-- > 0); | |
return NULL; | |
} | |
int main(int argc, const char * argv[]) | |
{ | |
size_t i = 0; | |
pid_t process[5]; | |
xsem_t children[5]; | |
xsem_t parent; | |
for (; i < 5; i++) { | |
xsem_init(&children[i], 1 , 0); | |
} | |
xsem_init(&parent, 1, 1); | |
for (i = 0; i < 5; i++) { | |
process[i]= fork(); | |
if (0 == process[i] ) { | |
write(STDOUT_FILENO, "fork\n", 5); | |
sleep(1); | |
while (1) { | |
write(STDOUT_FILENO, "ping\n", 5); | |
sleep(1); | |
xsem_wait(&children[i]); | |
++i; | |
if(i >= 5) { | |
i = 0; | |
xsem_post(&parent); | |
} | |
write(STDOUT_FILENO, "pong\n", 5); | |
sleep(1); | |
xsem_post(&children[i]); | |
} | |
} else { | |
continue; | |
} | |
} | |
while (1) { | |
xsem_wait(&parent); | |
for (i = 0; i < 5; i++) { | |
xsem_post(&children[i]); | |
} | |
} | |
for (; i < 5; i++) { | |
xsem_destroy(&children[i]); | |
} | |
xsem_destroy(&parent); | |
return 0; | |
} | |
/* EOF */ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@maxencejded @peiliny my take on binary semaphores.
So it is destructive by pair run, that's just to demonstrate that posix named semaphores are by definition shared ; the rational would be to create then close once ; then processes re-open existing pair in read/write and write/read mode then close. The main process will unlink final when exiting. @see documentation.
I don't see much any advantage in using unnamed semaphores ; using a descriptor rather than accessing them by name. Macosx doesn't support posix unnamed semaphore for historical reason ; i.e internal per process open file table addr size i.e 64bit. Terry Lambert before leaving the core os team did some work in that area but it has never been upstreamed.