Skip to content

Instantly share code, notes, and snippets.

@happyzleaf
Created February 7, 2022 18:47
Show Gist options
  • Save happyzleaf/7086a053a54ac1c1c1f0084209822da1 to your computer and use it in GitHub Desktop.
Save happyzleaf/7086a053a54ac1c1c1f0084209822da1 to your computer and use it in GitHub Desktop.
Personal Implementation of Signals using pipes
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
void s_init(int **S, int k);
void s_destroy(int *S);
void s_wait(int *S);
void s_signal(int *S);
void s_check_pipe(int *S) {
if (S == NULL) {
printf("The pipe is NULL.\n");
exit(1);
}
if (sizeof(S) != (sizeof(int) * 2)) {
printf("The pipe doesn't have the correct size.\n");
exit(1);
}
}
void s_init(int **S, int k) {
if (k < 0) {
printf("K must not be negative.\n");
exit(1);
}
*S = malloc(sizeof(int) * 2);
if (pipe(*S) == -1) {
printf("Couldn't create the pipe.\n");
exit(1);
}
for (int i = 0; i < k; i++) {
s_signal(*S);
}
}
void s_destroy(int *S) {
s_check_pipe(S);
close(S[0]);
close(S[1]);
}
void s_wait(int *S) {
s_check_pipe(S);
char ctr;
if (read(S[0], &ctr, 1) != 1) {
printf("Could not read from the pipe.\n");
exit(1);
}
}
void s_signal(int *S) {
s_check_pipe(S);
char ctr = 'X';
if (write(S[1], &ctr, 1) != 1) {
printf("Could not write to the pipe.\n");
exit(1);
}
}
int *s1;
int *s2;
_Noreturn void *t1(void *arg);
_Noreturn void *t2(void *arg);
int main() {
printf("[Main] Generating semaphores...\n");
s_init(&s1, 1);
s_init(&s2, 0);
printf("[Main] Starting threads...\n");
pthread_t ts[2];
if (pthread_create(&ts[0], NULL, (void *(*)(void *)) t1, (void *) 0) != 0) {
printf("[Main] Could not create thread T1.\n");
return 1;
}
sleep(5);
if (pthread_create(&ts[1], NULL, (void *(*)(void *)) t2, (void *) 1) != 0) {
printf("[Main] Could not create thread T2.\n");
return 1;
}
int ts_size = sizeof(ts) / sizeof(ts[0]);
// while (1) {
// sleep(1);
// for (int i = 0; i < ts_size; i++) {
// if (pthread_kill(ts[i], 0) == ESRCH) {
// printf("[Main] T%d is dead.", i + 1);
// }
// }
// }
for (int i = 0; i < ts_size; i++) {
if (pthread_join(ts[i], NULL) != 0) {
printf("[Main] Could not join thread T%d.\n", i + 1);
return 1;
}
}
printf("[Main] All threads returned.\n");
printf("[Main] Destroying semaphores...\n");
s_destroy(s1);
s_destroy(s2);
return 0;
}
int milk = 0;
void testMilk(char *prefix) {
if (milk < 1) {
printf("[%s] Not enough milk! Buying some...\n", prefix);
sleep(3);
milk++;
printf("[%s] Bought!\n", prefix);
} else {
printf("[%s] Milk available. Using some...\n", prefix);
sleep(3);
milk--;
printf("[%s] Used!\n", prefix);
}
printf("[%s] Fridge: %d milk\n", prefix, milk);
}
_Noreturn void *t1(void *arg) {
while (1) {
s_wait(s1);
testMilk("T1"); // SC
s_signal(s2);
sleep(1);
}
}
_Noreturn void *t2(void *arg) {
while (1) {
s_wait(s2);
testMilk("T2"); // SC
s_signal(s1);
sleep(1);
}
}
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
void s_init(int **S, int k);
void s_destroy(int *S);
void s_wait(int *S);
void s_signal(int *S);
void s_check_pipe(int *S) {
if (S == NULL) {
printf("The pipe is NULL.\n");
exit(1);
}
if (sizeof(S) != (sizeof(int) * 2)) {
printf("The pipe doesn't have the correct size.\n");
exit(1);
}
}
void s_init(int **S, int k) {
if (k < 0) {
printf("K must not be negative.\n");
exit(1);
}
*S = malloc(sizeof(int) * 2);
if (pipe(*S) == -1) {
printf("Couldn't create the pipe.\n");
exit(1);
}
for (int i = 0; i < k; i++) {
s_signal(*S);
}
}
void s_destroy(int *S) {
s_check_pipe(S);
close(S[0]);
close(S[1]);
}
void s_wait(int *S) {
s_check_pipe(S);
char ctr;
if (read(S[0], &ctr, 1) != 1) {
printf("Could not read from the pipe.\n");
exit(1);
}
}
void s_signal(int *S) {
s_check_pipe(S);
char ctr = 'X';
if (write(S[1], &ctr, 1) != 1) {
printf("Could not write to the pipe.\n");
exit(1);
}
}
int *s1;
int main() {
printf("Creating sem.\n");
s_init(&s1, 1);
printf("Waiting signal.\n");
s_wait(s1);
printf("Sending signal.\n");
s_signal(s1);
printf("Waiting signal.\n");
s_wait(s1);
printf("Destroying sem.\n");
s_destroy(s1);
printf("Done. Bye!\n");
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment