Created
October 23, 2019 14:10
-
-
Save poi519/40c302753dea5cb89c220336c09236c3 to your computer and use it in GitHub Desktop.
Dining philosophers in C using WinApi. Running: philosophers.exe num_threads fix?
This file contains hidden or 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 <windows.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
int fix = FALSE; | |
DWORD WINAPI dine(LPVOID param); | |
typedef struct { | |
int id; | |
HANDLE mutex; | |
} Fork; | |
typedef struct { | |
int id; | |
Fork *left; | |
Fork *right; | |
} Philosopher; | |
int main(int argc, char **argv) { | |
int num = 3; | |
if (argc > 1) { | |
num = (int) strtol(argv[1], (char **) NULL, 10); | |
printf("%u\n", num); | |
} | |
if (num < 1) { | |
return 0; | |
} | |
if (argc > 2) { | |
fix = TRUE; | |
} | |
Fork *forks = malloc(num * sizeof(Fork)); | |
Philosopher *ph = malloc(num * sizeof(Philosopher)); | |
DWORD *threadIds = malloc(num * sizeof(DWORD)); | |
HANDLE *threads = malloc(num * sizeof(HANDLE)); | |
for (int i = 0; i < num; i++) { | |
forks[i].id = i; | |
forks[i].mutex = CreateMutex( | |
NULL, // default security attributes | |
FALSE, // initially not owned | |
NULL); // unnamed mutex | |
if (forks[i].mutex == NULL) { | |
printf("CreateMutex error"); | |
return 1; | |
} | |
} | |
for (int i = 0; i < num; i++) { | |
ph[i].id = i; | |
} | |
for (int i = 0; i < num - 1; i++) { | |
ph[i].left = &forks[i]; | |
ph[i].right = &forks[i + 1]; | |
} | |
ph[num - 1].left = &forks[num - 1]; | |
ph[num - 1].right = &forks[0]; | |
for (int i = 0; i < num; i++) { | |
threads[i] = CreateThread( | |
NULL, | |
0, | |
dine, | |
&ph[i], | |
0, | |
&threadIds[i]); | |
if (threads[i] == NULL) { | |
printf("Error creating thread"); | |
ExitProcess(3); | |
} | |
} | |
WaitForMultipleObjects(num, threads, TRUE, INFINITE); | |
free(forks); | |
free(ph); | |
free(threads); | |
free(threadIds); | |
return 0; | |
} | |
void acquireFork(Philosopher *phi, Fork *f) { | |
DWORD waitResult; | |
printf("Philosopher %u, acquiring fork %u \n", phi->id, f->id); | |
waitResult = WaitForSingleObject(f->mutex, INFINITE); | |
switch (waitResult) { | |
case WAIT_OBJECT_0: { | |
printf("Philosopher %u, acquired fork %u \n", phi->id, f->id); | |
break; | |
} | |
case WAIT_ABANDONED: { | |
printf("Philsopher %u, abandoned wait for fork %u \n", phi->id, f->id); | |
} | |
} | |
} | |
void releaseFork(Philosopher *phi, Fork *f) { | |
printf("Philosopher %u, releasing fork %u \n", phi->id, f->id); | |
if (!ReleaseMutex(f->mutex)) { | |
printf("Philosopher %u, cannot release fork %u \n", phi->id, f->id); | |
} | |
} | |
DWORD WINAPI dine(LPVOID param) { | |
Philosopher *phi = (Philosopher *) param; | |
Fork *first = phi->left; | |
Fork *last = phi->right; | |
if (fix) { | |
if (phi->right->id < phi->left->id) { | |
first = phi->right; | |
last = phi->left; | |
} | |
} | |
acquireFork(phi, first); | |
Sleep(100); | |
acquireFork(phi, last); | |
printf("Philosopher %u dining\n", phi->id); | |
Sleep(1000); | |
releaseFork(phi, first); | |
Sleep(100); | |
releaseFork(phi, last); | |
return TRUE; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Dining philosophers in C using WinApi.
Running:
philosophers.exe num_threads fix?
philosophers.exe 10
- create 10 threads deadlock pronephilosophers.exe 10 fix
- create 10 threads with deadlock fix