{"id":21229847,"url":"https://github.com/sleleu/philosophers","last_synced_at":"2026-01-03T08:58:26.694Z","repository":{"id":111720456,"uuid":"519862418","full_name":"Sleleu/philosophers","owner":"Sleleu","description":"A multi-threaded program to solve the dining philosophers problem","archived":false,"fork":false,"pushed_at":"2024-09-10T15:57:49.000Z","size":59,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-09-10T17:44:58.678Z","etag":null,"topics":["42","c","concurrent-programming","multithreading"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Sleleu.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-07-31T18:56:28.000Z","updated_at":"2024-09-10T15:58:42.000Z","dependencies_parsed_at":null,"dependency_job_id":"0d020f12-963a-4d71-9c31-bc1f336ca2ee","html_url":"https://github.com/Sleleu/philosophers","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Sleleu%2Fphilosophers","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Sleleu%2Fphilosophers/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Sleleu%2Fphilosophers/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Sleleu%2Fphilosophers/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Sleleu","download_url":"https://codeload.github.com/Sleleu/philosophers/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225646809,"owners_count":17501937,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["42","c","concurrent-programming","multithreading"],"created_at":"2024-11-20T23:29:57.729Z","updated_at":"2026-01-03T08:58:26.652Z","avatar_url":"https://github.com/Sleleu.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# philosophers\n\n![huber](https://user-images.githubusercontent.com/93100775/186047534-422cfcbc-ff69-4d12-a6f3-2c5fa03ffdfd.jpg)\n\u003e_Jean Huber, Le Dîner des philosophes, 1772-1773, Voltaire Foundation, Oxford._\n\n# Project\n\nThis project is an introduction to **concurrent programming** with threads, whose objective is to solve the famous dining philosophers's problem.\n\n## Rules\n\n- One or more philosophers sit at a round table. There is a large bowl of spaghetti in the middle of the table.\n- The philosophers alternatively **eat, think,** or **sleep**. While they are eating, they are not thinking nor sleeping, while thinking, they are not eating nor sleeping, and while sleeping, they are not eating nor thinking.\n- There are also forks on the table. There are **as many forks as philosophers**.\n- A philosopher takes their right and their left forks to eat, one in each hand.\n- When a philosopher has finished eating, they put their forks back on the table and start sleeping. Once awake, they start thinking again. The simulation stops when a philosopher dies of starvation.\n- Every philosopher needs to eat and should never starve.\n- Philosophers don't speak with each other.\n- Philosophers don't know if another philosopher is about to die.\n- Philosophers should avoid dying.\n\n- Global variables are forbidden.\n- Each philosopher has a number ranging from 1 to nb_of_philo.\n- Philosopher number 1 sits next to philosopher number number_of_philosophers. Any other philosopher number N sits between philosopher number N - 1 and philosopher number N + 1.\n\nThe program will run with these following arguments :\n```C\n./philo [nb_of_philo] [time_to_die] [time_to_eat] [time_to_sleep] [time_each_philo_must_eat](optional)\n```\nAny state change of a philosopher must be formatted as follows:\n```C\n◦ timestamp_in_ms X has taken a fork\n◦ timestamp_in_ms X is eating\n◦ timestamp_in_ms X is sleeping\n◦ timestamp_in_ms X is thinking\n◦ timestamp_in_ms X died\n```\n- A displayed state message should not be mixed up with another message.\n- A message announcing a philosopher died should be displayed no more than 10 ms\nafter the actual death of the philosopher.\n\n# Notions\n\n## Threads\n\nA **thread** is a logical flow that runs in the context of a process. Each thread are scheduled has its own thread ID (TID), stack, stack pointer, program counter, and condition codes. With logical flows based on threads, multiple threads run in the context of a single process. Unlike proccesses, threads aren't organized in a parent-child hierarchy, they form an independant pool of peers. This means that each peer can kill any other peer without impacting any process tree. Furthermore, each peer can read and write the same shared data.\n\nA thread has several advantages :\n\n- **Reactivity** : The process continues to run even if some parts are blocked\n- **Ressource sharing**\n- **Saving memory, space and time** : A thread context is much smaller than a process context. For example, under the Solaris OS, creating a process is 30 times slower than creating a threaded process.\n\nTo manipulate threads in C programs, there are a standard interface called **Posix threads** (pthreads), who define several functions. This project only allow these functions from `\u003cpthread.h\u003e` :\n- pthread_create\n- pthread_detach\n- pthread_join\n- pthread_mutex_init\n- pthread_mutex_destroy\n- pthread_mutex_lock\n- pthread_mutex_unlock\n\n### Creating threads\n\nWe can use `pthread_create` which is prototyped as follows :\n\n```C\nint pthread_create(pthread_t *tid, pthread_attr_t *attr, func *f, void *arg);\n```\nThis function create a thread, and run a **thread routine** function. If we want neither attributes nor arguments in the routine, we can put a NULL _attr_ and/or NULL _arg_. Otherwise we can place a single pointer, or a pointer to structure if we want multiple arguments. To pass a structure in the routine function :\n\n```C\nvoid* routine(void *arg)\n{\n  t_struct *data;\n  \n  data = (t_struct *)arg;\n}\n```\n### Reaping terminated threads\n\n```C\nint pthread_join(pthread_t tid, void **thread_return);\n```\n\nThis function blocks until threads TID terminates, and reaps any memory ressources held by the terminated thread.\n\n### Detaching threads\n\n```C\nint pthread_detach(pthread_t tid);\n```\n\nAt any point in time, a thread is **joinable** or **detached**. In the joinable state, a thread can be reaped or killed by his peers, and memory resources aren't freed until it's reaped. Inversely, memory resources are freed automatically by the system when it terminates with a detached state.\n\n### Shared variables with threads\n\nA variable is shared only if one of its instances is referenced by more than one thread. To access shared variables, it's important to implement a mechanism to protect a variable shared by several threads. This mecanisme is called **mutex** (MUTual EXclusion). A variable typed `pthread_mutex_t` can lock a shared memory zone.\n\nTo dynamically initialize a mutex, we can use to function `pthread_mutex_init` :\n\n```C\nint pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attributs);\n```\n\nThe lock/unlock system work with the functions `pthread_mutex_lock` and `pthread_mutex_unlock` :\n\n```C\npthread_mutex_lock(phtread_mutex_t *mutex);\n\n---\nlocked resources\n---\n\npthread_mutex_unlock(phtread_mutex_t *mutex);\n\n```\n### Deadlock\n\nGenerally, a set of processes is deadlocked if each process is waiting for the release of a resource that is allocated to another process in the set.\n\n## Usefull links\n\n- https://cours.polymtl.ca/inf2610/documentation/notes/chap4.pdf\n- https://www.cs.sfu.ca/~ashriram/Courses/CS295/assets/books/CSAPP_2016.pdf\n- https://www.youtube.com/watch?v=d9s_d28yJq0\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsleleu%2Fphilosophers","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsleleu%2Fphilosophers","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsleleu%2Fphilosophers/lists"}