Skip to content

Instantly share code, notes, and snippets.

@poi519
Created October 23, 2019 14:10
Show Gist options
  • Save poi519/40c302753dea5cb89c220336c09236c3 to your computer and use it in GitHub Desktop.
Save poi519/40c302753dea5cb89c220336c09236c3 to your computer and use it in GitHub Desktop.
Dining philosophers in C using WinApi. Running: philosophers.exe num_threads fix?
#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;
}
@poi519
Copy link
Author

poi519 commented Oct 23, 2019

Dining philosophers in C using WinApi.

Running: philosophers.exe num_threads fix?

philosophers.exe 10 - create 10 threads deadlock prone
philosophers.exe 10 fix - create 10 threads with deadlock fix

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment