Created
February 7, 2022 18:47
-
-
Save happyzleaf/7086a053a54ac1c1c1f0084209822da1 to your computer and use it in GitHub Desktop.
Personal Implementation of Signals using pipes
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
#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); | |
} | |
} |
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
#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