From 7ea11fb537d113f2ba680adcbfe2d34b6ac194fb Mon Sep 17 00:00:00 2001 From: Aleksandrs Date: Mon, 11 Apr 2022 18:31:26 +0200 Subject: [PATCH 1/6] added philosophers spark session --- spark-sessions/philosophers/readme.md | 207 +++++++++++ spark-sessions/philosophers/readme_mod.md | 405 ++++++++++++++++++++++ 2 files changed, 612 insertions(+) create mode 100644 spark-sessions/philosophers/readme.md create mode 100644 spark-sessions/philosophers/readme_mod.md diff --git a/spark-sessions/philosophers/readme.md b/spark-sessions/philosophers/readme.md new file mode 100644 index 0000000..589d074 --- /dev/null +++ b/spark-sessions/philosophers/readme.md @@ -0,0 +1,207 @@ +# Exercise 00 ~(20min) +##### [*Really good read about threads.*](https://csc-knu.github.io/sys-prog/books/Andrew%20S.%20Tanenbaum%20-%20Modern%20Operating%20Systems.pdf#%5B%7B%22num%22%3A3419%2C%22gen%22%3A0%7D%2C%7B%22name%22%3A%22XYZ%22%7D%2C16%2C753%2C1%5D) <- You can search this if you like. +## Lets Talk Threads +### Why use ***threads***? ~ (5min) + +### What are threads? ~ (5min) + +#### What are the differences between processes and threads ~ 5(min) + +# Ex 01 ~(20min) + +## Preamble: + +![image](https://user-images.githubusercontent.com/47741591/162574543-2bb3b5b9-33a4-4a9b-ab9e-31870473ad53.png) + +### Description: +Create a thread, see what it does, how it works. +### Goal to achieve: +Create a new thread that outputs this message! +```sh +$ ./ex01.out +Hi From thread. You can call me philosopher 0 +``` +#### Allowed functions: +> printf +> +> pthread_create, +> +> pthread_join +--- +### what is pthread_t ~(5min) +1. what data type is this? +### pthread_create ~ (5min) +1. How does the prototype look like? +2. What arguments does the function take? +3. What is void \*(\*start_routine)(void \*)? +4. How would you pass data to the start_routine function? +5. What is the attr argument? +### pthread_join ~ (5min) +1. How does the prototype look like? +2. What arguments does the function take? +3. What is void \*\*value_ptr used for? + +# Ex02 ~(5min - 10min) + +Goal: + +creat 20 threads that will print the following + +```ascii +Hi From thread. You can call me philosopher 0 +Hi From thread. You can call me philosopher 0 +Hi From thread. You can call me philosopher 0 +Hi From thread. You can call me philosopher 0 +Hi From thread. You can call me philosopher 0 +Hi From thread. You can call me philosopher 0 +Hi From thread. You can call me philosopher 0 +Hi From thread. You can call me philosopher 0 +Hi From thread. You can call me philosopher 0 +Hi From thread. You can call me philosopher 0 +Hi From thread. You can call me philosopher 0 +Hi From thread. You can call me philosopher 0 +Hi From thread. You can call me philosopher 0 +Hi From thread. You can call me philosopher 0 +Hi From thread. You can call me philosopher 0 +Hi From thread. You can call me philosopher 0 +Hi From thread. You can call me philosopher 0 +Hi From thread. You can call me philosopher 0 +Hi From thread. You can call me philosopher 0 +Hi From thread. You can call me philosopher 0 +Hi From thread. You can call me philosopher 0 +``` + +# Ex03 ~35min + +## Race conditions + +[Whatch a video about data races](https://www.youtube.com/watch?v=FY9livorrJI) + +1. What are race conditions? +2. What is a critical section? + +How to spot race conditions? + +Do you see a data race in this code? + +```C +//example code +#include +#include + +void *rutine(void *ptr) +{ + while (*(int *)ptr < 1000) + { + *(int *)ptr += 1; + } + printf("Done\n"); + return (NULL); +} + +int main() +{ + pthread_t thread; + int index; + + index = 0; + pthread_create(&thread, NULL, rutine, &index); + while (index < 10000) + { + index++; + } + pthread_join(thread, NULL); + return (0); +} +``` +### What are mutexes? + + What is the pthread_mutex_t data type? + +### pthread_mutex_init ~ 5(min) + + What does this function do? + +### pthread_mutex_destroy ~ 5(min) + + What does this function do? + Do you have to free the mutex? + +### pthread_mutex_lock ~ 5 (min) + +![image](https://user-images.githubusercontent.com/47741591/162641384-72f74c56-fbe1-41d2-9e72-5ecb59019dba.png) + + What does this function do? + Can you lock a mutex that is not inited? + +### pthread_mutex_unlock ~ 25 (min) + +![image](https://user-images.githubusercontent.com/47741591/162641393-60777fe9-a1bd-4660-aed0-c512019aee4d.png) + + What does this function do? + What happens when u unlock a mutex 2times? + +Goal: +Make a program that inits, locks, unlock and destroys a mutex! + +Goal: +Prevent the data race in the example code. + +# ex04 + +## Deadlocks + +What is a deadlock? +When does a deadlock occur? + + +#### Goal: + +Goal: +Produce a program that has a deadlock. + +# Break + +![image](https://user-images.githubusercontent.com/47741591/162641349-a2107f6e-85d9-47bf-8b9e-38a91aaa76d6.png) + +# ex05 +creat 20 threads that will print the following +the order does not matter + +```ascii +Hi From thread. You can call me philosopher 1 +Hi From thread. You can call me philosopher 2 +Hi From thread. You can call me philosopher 3 +Hi From thread. You can call me philosopher 4 +Hi From thread. You can call me philosopher 5 +Hi From thread. You can call me philosopher 6 +Hi From thread. You can call me philosopher 7 +Hi From thread. You can call me philosopher 8 +Hi From thread. You can call me philosopher 9 +Hi From thread. You can call me philosopher 10 +Hi From thread. You can call me philosopher 11 +Hi From thread. You can call me philosopher 12 +Hi From thread. You can call me philosopher 13 +Hi From thread. You can call me philosopher 14 +Hi From thread. You can call me philosopher 15 +Hi From thread. You can call me philosopher 16 +Hi From thread. You can call me philosopher 17 +Hi From thread. You can call me philosopher 18 +Hi From thread. You can call me philosopher 19 +Hi From thread. You can call me philosopher 20 +Hi From thread. You can call me philosopher 21 +``` + +# Bonus + +make a program that will use 3 created threads to add up an int to 42. Threads can increment the int every .5sec +once the value is 42 the program has to print "Got it!\n" and exit. + +catch: +The threads do not know when the value is 42 + +What is a monitoring thread? + +a monitoring thread is a concept used in the philosopher's project. a monitoring thread will keep track of the int variable. If the value is 42 let the threads know to finish and exit. + +![image](https://user-images.githubusercontent.com/47741591/162580113-4eb7f53e-cdd5-4055-8174-e06392e301fc.png) diff --git a/spark-sessions/philosophers/readme_mod.md b/spark-sessions/philosophers/readme_mod.md new file mode 100644 index 0000000..63de68a --- /dev/null +++ b/spark-sessions/philosophers/readme_mod.md @@ -0,0 +1,405 @@ +# Exercise 00 ~(20min) +##### [*Really good read about threads.*](https://csc-knu.github.io/sys-prog/books/Andrew%20S.%20Tanenbaum%20-%20Modern%20Operating%20Systems.pdf#%5B%7B%22num%22%3A3419%2C%22gen%22%3A0%7D%2C%7B%22name%22%3A%22XYZ%22%7D%2C16%2C753%2C1%5D) <- You can search this if you like. +## Lets Talk Threads +### Why use ***threads***? ~ (5min) +##### Answer +> 1. Creating a thread goes 10โ€“100 times faster than creating a process. +> 2. To shear address space +> 3. Performance +> 4. To work with blocking system calls +> 5. There is a blocking call + +### What are threads? ~ (5min) +##### Answer +> One way of looking at a process is that it is a way to group related resources. A process has an address space containing program text and data and other resources. These resources may include open files, child processes, pending alarms, signal handlers, accounting information, and more. By putting them together in the form of a process, they can be managed more easily. The other concept a process has is a ***thread*** of execution, usually shortened to just ***thread***. The ***thread*** has a program counter that keeps track of which instruc-tion to execute next. It has registers, which hold its current working variables. It has a stack, which contains the execution history, with one frame for each proce-dure called but not yet returned from. Although a ***thread*** must execute in some process, the ***thread*** and its process are different concepts and can be treated sepa-rately. Processes are used to group resources together; ***threads*** are the entities scheduled for execution on the CPU. + +#### What are the differences between processes and threads ~ 5(min) + +_Does not have to be exactly like this but make sure that every one gets the difference bewteen threads and processes_ +##### Answear +Screen Shot 2022-04-09 at 10 07 36 PM + +# Ex 01 ~(20min) + +## Preamble: + +![image](https://user-images.githubusercontent.com/47741591/162574543-2bb3b5b9-33a4-4a9b-ab9e-31870473ad53.png) + +### Description: +Create a thread, see what it does, how it works. +### Goal to achieve: +Create a new thread that outputs this message! +```sh +$ ./ex01.out +Hi From thread. You can call me philosopher 0 +``` +#### Allowed functions: +> printf +> +> pthread_create, +> +> pthread_join +--- +### what is pthread_t ~(5min) +1. what data type is this? +### pthread_create ~ (5min) +1. How does the prototype look like? +2. What arguments does the function take? +3. What is void \*(\*start_routine)(void \*)? +4. How would you pass data to the start_routine function? +5. What is the attr argument? +### pthread_join ~ (5min) +1. How does the prototype look like? +2. What arguments does the function take? +3. What is void \*\*value_ptr used for? +--- +###### ANSWEAR + +```C +#include +#include + +void *routine(void *ptr) +{ + printf("Hi From thread. You can call me philosopher 0\n"); + return (NULL); +} + +int main() +{ + pthread_t thread; + + pthread_create(&thread, NULL, routine, NULL); + pthread_join(thread, NULL); + return (0); +} +``` + +*When your programme is ready run* `unit_test.sh`. + +# Ex02 ~(5min - 10min) + +Goal: + +creat 20 threads that will print the following + +```ascii +Hi From thread. You can call me philosopher 0 +Hi From thread. You can call me philosopher 0 +Hi From thread. You can call me philosopher 0 +Hi From thread. You can call me philosopher 0 +Hi From thread. You can call me philosopher 0 +Hi From thread. You can call me philosopher 0 +Hi From thread. You can call me philosopher 0 +Hi From thread. You can call me philosopher 0 +Hi From thread. You can call me philosopher 0 +Hi From thread. You can call me philosopher 0 +Hi From thread. You can call me philosopher 0 +Hi From thread. You can call me philosopher 0 +Hi From thread. You can call me philosopher 0 +Hi From thread. You can call me philosopher 0 +Hi From thread. You can call me philosopher 0 +Hi From thread. You can call me philosopher 0 +Hi From thread. You can call me philosopher 0 +Hi From thread. You can call me philosopher 0 +Hi From thread. You can call me philosopher 0 +Hi From thread. You can call me philosopher 0 +Hi From thread. You can call me philosopher 0 +``` + +###### ANSWEAR + +```C +#include +#include + +#define MAX_PHILO 20 + +void *rutine(void *ptr) +{ + printf("Hi From thread. You can call me philosopher 0\n"); + return (NULL); +} + +int main() +{ + pthread_t thread[MAX_PHILO]; + + for (int i = 0; i < MAX_PHILO; i++) + { + pthread_create(&thread[i], NULL, rutine, NULL); + } + for (int i = 0; i < MAX_PHILO; i++) + { + pthread_join(thread[i], NULL); + } + return (0); +} +``` + +# Ex03 ~35min + +## Race conditions + +[Whatch a video about data races](https://www.youtube.com/watch?v=FY9livorrJI) + +1. What are race conditions? +2. What is a critical section? + +How to spot race conditions? +##### Answear +```-fsanitize=thread``` + +Do you see a data race in this code? + +```C +//example code +#include +#include + +void *rutine(void *ptr) +{ + while (*(int *)ptr < 1000) + { + *(int *)ptr += 1; + } + printf("Done\n"); + return (NULL); +} + +int main() +{ + pthread_t thread; + int index; + + index = 0; + pthread_create(&thread, NULL, rutine, &index); + while (index < 10000) + { + index++; + } + pthread_join(thread, NULL); + return (0); +} +``` +### What are mutexes? + + What is the pthread_mutex_t data type? + +### pthread_mutex_init ~ 5(min) + + What does this function do? + +### pthread_mutex_destroy ~ 5(min) + + What does this function do? + Do you have to free the mutex? + +### pthread_mutex_lock ~ 5 (min) + +![image](https://user-images.githubusercontent.com/47741591/162641384-72f74c56-fbe1-41d2-9e72-5ecb59019dba.png) + + What does this function do? + Can you lock a mutex that is not inited? + +### pthread_mutex_unlock ~ 25 (min) + +![image](https://user-images.githubusercontent.com/47741591/162641393-60777fe9-a1bd-4660-aed0-c512019aee4d.png) + + What does this function do? + What happens when u unlock a mutex 2times? + +Goal: +Make a program that inits, locks, unlock and destroys a mutex! + +```C +#include + +int main() +{ + pthread_mutex_t lock; + + pthread_mutex_init(&lock, NULL); + pthread_mutex_lock(&lock); + pthread_mutex_unlock(&lock); + pthread_mutex_destroy(&lock); + return (0); +} +``` + +Goal: +Prevent the data race in the example code. + +# ex04 + +## Deadlocks + +What is a deadlock? +When does a deadlock occur? + + +#### Goal: + +Goal: +Produce a program that has a deadlock. + +### Answear + +```C +#include + +int main() +{ + pthread_mutex_t lock; + + pthread_mutex_init(&lock, NULL); + pthread_mutex_lock(&lock); + pthread_mutex_lock(&lock); + pthread_mutex_unlock(&lock); + pthread_mutex_destroy(&lock); + return (0); +} +``` + +# Break + +![image](https://user-images.githubusercontent.com/47741591/162641349-a2107f6e-85d9-47bf-8b9e-38a91aaa76d6.png) + +# ex05 +creat 20 threads that will print the following +the order does not matter + +```ascii +Hi From thread. You can call me philosopher 1 +Hi From thread. You can call me philosopher 2 +Hi From thread. You can call me philosopher 3 +Hi From thread. You can call me philosopher 4 +Hi From thread. You can call me philosopher 5 +Hi From thread. You can call me philosopher 6 +Hi From thread. You can call me philosopher 7 +Hi From thread. You can call me philosopher 8 +Hi From thread. You can call me philosopher 9 +Hi From thread. You can call me philosopher 10 +Hi From thread. You can call me philosopher 11 +Hi From thread. You can call me philosopher 12 +Hi From thread. You can call me philosopher 13 +Hi From thread. You can call me philosopher 14 +Hi From thread. You can call me philosopher 15 +Hi From thread. You can call me philosopher 16 +Hi From thread. You can call me philosopher 17 +Hi From thread. You can call me philosopher 18 +Hi From thread. You can call me philosopher 19 +Hi From thread. You can call me philosopher 20 +Hi From thread. You can call me philosopher 21 +``` + +##### Answear + +```C +#include +#include + +typedef struct s_list +{ + int index; + pthread_mutex_t lock; +} t_list; + +#define MAX_PHILO 20 + +void *rutine(void *ptr) +{ + pthread_mutex_lock(&((t_list *)ptr)->lock); + printf("Hi From thread. You can call me philosopher %d\n", (*(t_list *)ptr).index + 1); + pthread_mutex_unlock(&((t_list *)ptr)->lock); + return (NULL); +} + +int main() +{ + pthread_t thread[MAX_PHILO]; + t_list philosopher[MAX_PHILO]; + + for (int i = 0; i < 20; i++) + { + pthread_mutex_init(&philosopher[i].lock, NULL); + pthread_mutex_lock(&philosopher[i].lock); + philosopher[i].index = i; + pthread_mutex_unlock(&philosopher[i].lock); + pthread_create(&thread[i], NULL, rutine, &philosopher[i]); + } + for (int i = 0; i < MAX_PHILO; i++) + { + pthread_join(thread[i], NULL); + pthread_mutex_destroy(&philosopher[i].lock); + } + return (0); +} +``` + +# Bonus + +make a program that will use 3 created threads to add up an int to 42. Threads can increment the int every .5sec +once the value is 42 the program has to print "Got it!\n" and exit. + +catch: +The threads do not know when the value is 42 + +What is a monitoring thread? + +a monitoring thread is a concept used in the philosopher's project. a monitoring thread will keep track of the int variable. If the value is 42 let the threads know to finish and exit. + +```C +#include +#include +#include +#include + +typedef struct s_data +{ + bool is_done; + pthread_mutex_t mutex_lock; +} t_data; + +void *rutine(void *ptr) +{ + t_data *data = ptr; + + while (1) + { + pthread_mutex_lock(&data->mutex_lock); + if (data->is_done) + { + printf("I am dead\n"); + pthread_mutex_unlock(&data->mutex_lock); + return (NULL); + } + pthread_mutex_unlock(&data->mutex_lock); + sleep(1); + printf("I am still alive\n"); + } + return (NULL); +} + +int main() +{ + pthread_t thread[4]; + t_data data; + + + data.is_done = false; + pthread_mutex_init(&data.mutex_lock, NULL); + for (int i = 0; i < 4; i++) + pthread_create(&thread[i], NULL, rutine, &data); + sleep(5); + pthread_mutex_lock(&data.mutex_lock); + data.is_done = true; + pthread_mutex_unlock(&data.mutex_lock); + for (int i = 0; i < 4; i++) + pthread_join(thread[i], NULL); + pthread_mutex_destroy(&data.mutex_lock); + return (0); +} +``` + +![image](https://user-images.githubusercontent.com/47741591/162580113-4eb7f53e-cdd5-4055-8174-e06392e301fc.png) From 86a3b2f6433465d4611a1c313a7f9b53682a1bae Mon Sep 17 00:00:00 2001 From: SirMorfield Date: Tue, 12 Apr 2022 11:05:49 +0200 Subject: [PATCH 2/6] fix: rename files --- .../{readme_mod.md => SparkSession - philosophers - mod.md} | 0 .../philosophers/{readme.md => SparkSession - philosophers.md} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename spark-sessions/philosophers/{readme_mod.md => SparkSession - philosophers - mod.md} (100%) rename spark-sessions/philosophers/{readme.md => SparkSession - philosophers.md} (100%) diff --git a/spark-sessions/philosophers/readme_mod.md b/spark-sessions/philosophers/SparkSession - philosophers - mod.md similarity index 100% rename from spark-sessions/philosophers/readme_mod.md rename to spark-sessions/philosophers/SparkSession - philosophers - mod.md diff --git a/spark-sessions/philosophers/readme.md b/spark-sessions/philosophers/SparkSession - philosophers.md similarity index 100% rename from spark-sessions/philosophers/readme.md rename to spark-sessions/philosophers/SparkSession - philosophers.md From 84c7b95b646b97a357b9d7c681f0e72180c2a011 Mon Sep 17 00:00:00 2001 From: SirMorfield Date: Tue, 12 Apr 2022 15:30:42 +0200 Subject: [PATCH 3/6] fix: spelling, formatting, remove images --- .../SparkSession - philosophers - mod.md | 37 ++++------ .../SparkSession - philosophers.md | 67 +++++++------------ 2 files changed, 37 insertions(+), 67 deletions(-) diff --git a/spark-sessions/philosophers/SparkSession - philosophers - mod.md b/spark-sessions/philosophers/SparkSession - philosophers - mod.md index 63de68a..ac24a43 100644 --- a/spark-sessions/philosophers/SparkSession - philosophers - mod.md +++ b/spark-sessions/philosophers/SparkSession - philosophers - mod.md @@ -16,7 +16,7 @@ #### What are the differences between processes and threads ~ 5(min) _Does not have to be exactly like this but make sure that every one gets the difference bewteen threads and processes_ -##### Answear +##### Answer Screen Shot 2022-04-09 at 10 07 36 PM # Ex 01 ~(20min) @@ -53,7 +53,7 @@ Hi From thread. You can call me philosopher 0 2. What arguments does the function take? 3. What is void \*\*value_ptr used for? --- -###### ANSWEAR +###### Answer ```C #include @@ -107,7 +107,7 @@ Hi From thread. You can call me philosopher 0 Hi From thread. You can call me philosopher 0 ``` -###### ANSWEAR +###### Answer ```C #include @@ -147,13 +147,13 @@ int main() 2. What is a critical section? How to spot race conditions? -##### Answear +##### Answer ```-fsanitize=thread``` Do you see a data race in this code? ```C -//example code +// example code #include #include @@ -170,7 +170,7 @@ void *rutine(void *ptr) int main() { pthread_t thread; - int index; + int index; index = 0; pthread_create(&thread, NULL, rutine, &index); @@ -184,11 +184,10 @@ int main() ``` ### What are mutexes? - What is the pthread_mutex_t data type? - -### pthread_mutex_init ~ 5(min) +What is the pthread_mutex_t data type? - What does this function do? +### pthread_mutex_init ~ 5(min) +What does this function do? ### pthread_mutex_destroy ~ 5(min) @@ -197,19 +196,15 @@ int main() ### pthread_mutex_lock ~ 5 (min) -![image](https://user-images.githubusercontent.com/47741591/162641384-72f74c56-fbe1-41d2-9e72-5ecb59019dba.png) - What does this function do? Can you lock a mutex that is not inited? ### pthread_mutex_unlock ~ 25 (min) -![image](https://user-images.githubusercontent.com/47741591/162641393-60777fe9-a1bd-4660-aed0-c512019aee4d.png) - What does this function do? What happens when u unlock a mutex 2times? -Goal: +Goal: Make a program that inits, locks, unlock and destroys a mutex! ```C @@ -243,7 +238,7 @@ When does a deadlock occur? Goal: Produce a program that has a deadlock. -### Answear +### Answer ```C #include @@ -263,8 +258,6 @@ int main() # Break -![image](https://user-images.githubusercontent.com/47741591/162641349-a2107f6e-85d9-47bf-8b9e-38a91aaa76d6.png) - # ex05 creat 20 threads that will print the following the order does not matter @@ -293,7 +286,7 @@ Hi From thread. You can call me philosopher 20 Hi From thread. You can call me philosopher 21 ``` -##### Answear +##### Answer ```C #include @@ -339,7 +332,7 @@ int main() # Bonus -make a program that will use 3 created threads to add up an int to 42. Threads can increment the int every .5sec +Make a program that will use 3 created threads to add up an int to 42. Threads can increment the int every .5sec once the value is 42 the program has to print "Got it!\n" and exit. catch: @@ -347,7 +340,7 @@ The threads do not know when the value is 42 What is a monitoring thread? -a monitoring thread is a concept used in the philosopher's project. a monitoring thread will keep track of the int variable. If the value is 42 let the threads know to finish and exit. +A monitoring thread is a concept used in the philosopher's project. a monitoring thread will keep track of the int variable. If the value is 42 let the threads know to finish and exit. ```C #include @@ -401,5 +394,3 @@ int main() return (0); } ``` - -![image](https://user-images.githubusercontent.com/47741591/162580113-4eb7f53e-cdd5-4055-8174-e06392e301fc.png) diff --git a/spark-sessions/philosophers/SparkSession - philosophers.md b/spark-sessions/philosophers/SparkSession - philosophers.md index 589d074..45280d0 100644 --- a/spark-sessions/philosophers/SparkSession - philosophers.md +++ b/spark-sessions/philosophers/SparkSession - philosophers.md @@ -1,18 +1,11 @@ -# Exercise 00 ~(20min) -##### [*Really good read about threads.*](https://csc-knu.github.io/sys-prog/books/Andrew%20S.%20Tanenbaum%20-%20Modern%20Operating%20Systems.pdf#%5B%7B%22num%22%3A3419%2C%22gen%22%3A0%7D%2C%7B%22name%22%3A%22XYZ%22%7D%2C16%2C753%2C1%5D) <- You can search this if you like. +# Exercise 00 ~(20min)##### [*Really good read about threads.*](https://csc-knu.github.io/sys-prog/books/Andrew%20S.%20Tanenbaum%20-%20Modern%20Operating%20Systems.pdf#%5B%7B%22num%22%3A3419%2C%22gen%22%3A0%7D%2C%7B%22name%22%3A%22XYZ%22%7D%2C16%2C753%2C1%5D) ## Lets Talk Threads -### Why use ***threads***? ~ (5min) - -### What are threads? ~ (5min) - -#### What are the differences between processes and threads ~ 5(min) +- Why use ***threads***? ~ (5min) +- What are threads? ~ (5min) +- What are the differences between processes and threads ~ 5(min) # Ex 01 ~(20min) -## Preamble: - -![image](https://user-images.githubusercontent.com/47741591/162574543-2bb3b5b9-33a4-4a9b-ab9e-31870473ad53.png) - ### Description: Create a thread, see what it does, how it works. ### Goal to achieve: @@ -22,30 +15,26 @@ $ ./ex01.out Hi From thread. You can call me philosopher 0 ``` #### Allowed functions: -> printf -> -> pthread_create, -> -> pthread_join + +```printf pthread_create pthread_join``` + --- ### what is pthread_t ~(5min) -1. what data type is this? +1. What is the prototype? ### pthread_create ~ (5min) -1. How does the prototype look like? -2. What arguments does the function take? -3. What is void \*(\*start_routine)(void \*)? -4. How would you pass data to the start_routine function? -5. What is the attr argument? +1. What is the prototype? +2. What is `void \*(\*start_routine)(void \*)` +3. How would you pass data to the start_routine function? +4. What is the attr argument? ### pthread_join ~ (5min) -1. How does the prototype look like? -2. What arguments does the function take? -3. What is void \*\*value_ptr used for? +1. What is the prototype? +2. What is void \*\*value_ptr used for? # Ex02 ~(5min - 10min) Goal: -creat 20 threads that will print the following +Create 20 threads that will print the following ```ascii Hi From thread. You can call me philosopher 0 @@ -68,7 +57,6 @@ Hi From thread. You can call me philosopher 0 Hi From thread. You can call me philosopher 0 Hi From thread. You can call me philosopher 0 Hi From thread. You can call me philosopher 0 -Hi From thread. You can call me philosopher 0 ``` # Ex03 ~35min @@ -85,7 +73,7 @@ How to spot race conditions? Do you see a data race in this code? ```C -//example code +// example code #include #include @@ -102,7 +90,7 @@ void *rutine(void *ptr) int main() { pthread_t thread; - int index; + int index; index = 0; pthread_create(&thread, NULL, rutine, &index); @@ -116,11 +104,10 @@ int main() ``` ### What are mutexes? - What is the pthread_mutex_t data type? - -### pthread_mutex_init ~ 5(min) +What is the pthread_mutex_t data type? - What does this function do? +### pthread_mutex_init ~ 5(min) +What does this function do? ### pthread_mutex_destroy ~ 5(min) @@ -129,19 +116,15 @@ int main() ### pthread_mutex_lock ~ 5 (min) -![image](https://user-images.githubusercontent.com/47741591/162641384-72f74c56-fbe1-41d2-9e72-5ecb59019dba.png) - What does this function do? Can you lock a mutex that is not inited? ### pthread_mutex_unlock ~ 25 (min) -![image](https://user-images.githubusercontent.com/47741591/162641393-60777fe9-a1bd-4660-aed0-c512019aee4d.png) - What does this function do? What happens when u unlock a mutex 2times? -Goal: +Goal: Make a program that inits, locks, unlock and destroys a mutex! Goal: @@ -162,8 +145,6 @@ Produce a program that has a deadlock. # Break -![image](https://user-images.githubusercontent.com/47741591/162641349-a2107f6e-85d9-47bf-8b9e-38a91aaa76d6.png) - # ex05 creat 20 threads that will print the following the order does not matter @@ -194,7 +175,7 @@ Hi From thread. You can call me philosopher 21 # Bonus -make a program that will use 3 created threads to add up an int to 42. Threads can increment the int every .5sec +Make a program that will use 3 created threads to add up an int to 42. Threads can increment the int every .5sec once the value is 42 the program has to print "Got it!\n" and exit. catch: @@ -202,6 +183,4 @@ The threads do not know when the value is 42 What is a monitoring thread? -a monitoring thread is a concept used in the philosopher's project. a monitoring thread will keep track of the int variable. If the value is 42 let the threads know to finish and exit. - -![image](https://user-images.githubusercontent.com/47741591/162580113-4eb7f53e-cdd5-4055-8174-e06392e301fc.png) +A monitoring thread is a concept used in the philosopher's project. a monitoring thread will keep track of the int variable. If the value is 42 let the threads know to finish and exit. From ed151e778eecc5d3831da3a07479280a36630fb3 Mon Sep 17 00:00:00 2001 From: Aleksandrs Date: Thu, 19 May 2022 13:51:44 +0200 Subject: [PATCH 4/6] Add proper sessions notes --- .../SparkSession - philosophers - mod.md | 396 --------- .../SparkSession - philosophers.md | 186 ---- .../SparkSession -philosophers - mod.md | 815 ++++++++++++++++++ .../SparkSession -philosophers.md | 453 ++++++++++ 4 files changed, 1268 insertions(+), 582 deletions(-) delete mode 100644 spark-sessions/philosophers/SparkSession - philosophers - mod.md delete mode 100644 spark-sessions/philosophers/SparkSession - philosophers.md create mode 100644 spark-sessions/philosophers/SparkSession -philosophers - mod.md create mode 100644 spark-sessions/philosophers/SparkSession -philosophers.md diff --git a/spark-sessions/philosophers/SparkSession - philosophers - mod.md b/spark-sessions/philosophers/SparkSession - philosophers - mod.md deleted file mode 100644 index ac24a43..0000000 --- a/spark-sessions/philosophers/SparkSession - philosophers - mod.md +++ /dev/null @@ -1,396 +0,0 @@ -# Exercise 00 ~(20min) -##### [*Really good read about threads.*](https://csc-knu.github.io/sys-prog/books/Andrew%20S.%20Tanenbaum%20-%20Modern%20Operating%20Systems.pdf#%5B%7B%22num%22%3A3419%2C%22gen%22%3A0%7D%2C%7B%22name%22%3A%22XYZ%22%7D%2C16%2C753%2C1%5D) <- You can search this if you like. -## Lets Talk Threads -### Why use ***threads***? ~ (5min) -##### Answer -> 1. Creating a thread goes 10โ€“100 times faster than creating a process. -> 2. To shear address space -> 3. Performance -> 4. To work with blocking system calls -> 5. There is a blocking call - -### What are threads? ~ (5min) -##### Answer -> One way of looking at a process is that it is a way to group related resources. A process has an address space containing program text and data and other resources. These resources may include open files, child processes, pending alarms, signal handlers, accounting information, and more. By putting them together in the form of a process, they can be managed more easily. The other concept a process has is a ***thread*** of execution, usually shortened to just ***thread***. The ***thread*** has a program counter that keeps track of which instruc-tion to execute next. It has registers, which hold its current working variables. It has a stack, which contains the execution history, with one frame for each proce-dure called but not yet returned from. Although a ***thread*** must execute in some process, the ***thread*** and its process are different concepts and can be treated sepa-rately. Processes are used to group resources together; ***threads*** are the entities scheduled for execution on the CPU. - -#### What are the differences between processes and threads ~ 5(min) - -_Does not have to be exactly like this but make sure that every one gets the difference bewteen threads and processes_ -##### Answer -Screen Shot 2022-04-09 at 10 07 36 PM - -# Ex 01 ~(20min) - -## Preamble: - -![image](https://user-images.githubusercontent.com/47741591/162574543-2bb3b5b9-33a4-4a9b-ab9e-31870473ad53.png) - -### Description: -Create a thread, see what it does, how it works. -### Goal to achieve: -Create a new thread that outputs this message! -```sh -$ ./ex01.out -Hi From thread. You can call me philosopher 0 -``` -#### Allowed functions: -> printf -> -> pthread_create, -> -> pthread_join ---- -### what is pthread_t ~(5min) -1. what data type is this? -### pthread_create ~ (5min) -1. How does the prototype look like? -2. What arguments does the function take? -3. What is void \*(\*start_routine)(void \*)? -4. How would you pass data to the start_routine function? -5. What is the attr argument? -### pthread_join ~ (5min) -1. How does the prototype look like? -2. What arguments does the function take? -3. What is void \*\*value_ptr used for? ---- -###### Answer - -```C -#include -#include - -void *routine(void *ptr) -{ - printf("Hi From thread. You can call me philosopher 0\n"); - return (NULL); -} - -int main() -{ - pthread_t thread; - - pthread_create(&thread, NULL, routine, NULL); - pthread_join(thread, NULL); - return (0); -} -``` - -*When your programme is ready run* `unit_test.sh`. - -# Ex02 ~(5min - 10min) - -Goal: - -creat 20 threads that will print the following - -```ascii -Hi From thread. You can call me philosopher 0 -Hi From thread. You can call me philosopher 0 -Hi From thread. You can call me philosopher 0 -Hi From thread. You can call me philosopher 0 -Hi From thread. You can call me philosopher 0 -Hi From thread. You can call me philosopher 0 -Hi From thread. You can call me philosopher 0 -Hi From thread. You can call me philosopher 0 -Hi From thread. You can call me philosopher 0 -Hi From thread. You can call me philosopher 0 -Hi From thread. You can call me philosopher 0 -Hi From thread. You can call me philosopher 0 -Hi From thread. You can call me philosopher 0 -Hi From thread. You can call me philosopher 0 -Hi From thread. You can call me philosopher 0 -Hi From thread. You can call me philosopher 0 -Hi From thread. You can call me philosopher 0 -Hi From thread. You can call me philosopher 0 -Hi From thread. You can call me philosopher 0 -Hi From thread. You can call me philosopher 0 -Hi From thread. You can call me philosopher 0 -``` - -###### Answer - -```C -#include -#include - -#define MAX_PHILO 20 - -void *rutine(void *ptr) -{ - printf("Hi From thread. You can call me philosopher 0\n"); - return (NULL); -} - -int main() -{ - pthread_t thread[MAX_PHILO]; - - for (int i = 0; i < MAX_PHILO; i++) - { - pthread_create(&thread[i], NULL, rutine, NULL); - } - for (int i = 0; i < MAX_PHILO; i++) - { - pthread_join(thread[i], NULL); - } - return (0); -} -``` - -# Ex03 ~35min - -## Race conditions - -[Whatch a video about data races](https://www.youtube.com/watch?v=FY9livorrJI) - -1. What are race conditions? -2. What is a critical section? - -How to spot race conditions? -##### Answer -```-fsanitize=thread``` - -Do you see a data race in this code? - -```C -// example code -#include -#include - -void *rutine(void *ptr) -{ - while (*(int *)ptr < 1000) - { - *(int *)ptr += 1; - } - printf("Done\n"); - return (NULL); -} - -int main() -{ - pthread_t thread; - int index; - - index = 0; - pthread_create(&thread, NULL, rutine, &index); - while (index < 10000) - { - index++; - } - pthread_join(thread, NULL); - return (0); -} -``` -### What are mutexes? - -What is the pthread_mutex_t data type? - -### pthread_mutex_init ~ 5(min) -What does this function do? - -### pthread_mutex_destroy ~ 5(min) - - What does this function do? - Do you have to free the mutex? - -### pthread_mutex_lock ~ 5 (min) - - What does this function do? - Can you lock a mutex that is not inited? - -### pthread_mutex_unlock ~ 25 (min) - - What does this function do? - What happens when u unlock a mutex 2times? - -Goal: -Make a program that inits, locks, unlock and destroys a mutex! - -```C -#include - -int main() -{ - pthread_mutex_t lock; - - pthread_mutex_init(&lock, NULL); - pthread_mutex_lock(&lock); - pthread_mutex_unlock(&lock); - pthread_mutex_destroy(&lock); - return (0); -} -``` - -Goal: -Prevent the data race in the example code. - -# ex04 - -## Deadlocks - -What is a deadlock? -When does a deadlock occur? - - -#### Goal: - -Goal: -Produce a program that has a deadlock. - -### Answer - -```C -#include - -int main() -{ - pthread_mutex_t lock; - - pthread_mutex_init(&lock, NULL); - pthread_mutex_lock(&lock); - pthread_mutex_lock(&lock); - pthread_mutex_unlock(&lock); - pthread_mutex_destroy(&lock); - return (0); -} -``` - -# Break - -# ex05 -creat 20 threads that will print the following -the order does not matter - -```ascii -Hi From thread. You can call me philosopher 1 -Hi From thread. You can call me philosopher 2 -Hi From thread. You can call me philosopher 3 -Hi From thread. You can call me philosopher 4 -Hi From thread. You can call me philosopher 5 -Hi From thread. You can call me philosopher 6 -Hi From thread. You can call me philosopher 7 -Hi From thread. You can call me philosopher 8 -Hi From thread. You can call me philosopher 9 -Hi From thread. You can call me philosopher 10 -Hi From thread. You can call me philosopher 11 -Hi From thread. You can call me philosopher 12 -Hi From thread. You can call me philosopher 13 -Hi From thread. You can call me philosopher 14 -Hi From thread. You can call me philosopher 15 -Hi From thread. You can call me philosopher 16 -Hi From thread. You can call me philosopher 17 -Hi From thread. You can call me philosopher 18 -Hi From thread. You can call me philosopher 19 -Hi From thread. You can call me philosopher 20 -Hi From thread. You can call me philosopher 21 -``` - -##### Answer - -```C -#include -#include - -typedef struct s_list -{ - int index; - pthread_mutex_t lock; -} t_list; - -#define MAX_PHILO 20 - -void *rutine(void *ptr) -{ - pthread_mutex_lock(&((t_list *)ptr)->lock); - printf("Hi From thread. You can call me philosopher %d\n", (*(t_list *)ptr).index + 1); - pthread_mutex_unlock(&((t_list *)ptr)->lock); - return (NULL); -} - -int main() -{ - pthread_t thread[MAX_PHILO]; - t_list philosopher[MAX_PHILO]; - - for (int i = 0; i < 20; i++) - { - pthread_mutex_init(&philosopher[i].lock, NULL); - pthread_mutex_lock(&philosopher[i].lock); - philosopher[i].index = i; - pthread_mutex_unlock(&philosopher[i].lock); - pthread_create(&thread[i], NULL, rutine, &philosopher[i]); - } - for (int i = 0; i < MAX_PHILO; i++) - { - pthread_join(thread[i], NULL); - pthread_mutex_destroy(&philosopher[i].lock); - } - return (0); -} -``` - -# Bonus - -Make a program that will use 3 created threads to add up an int to 42. Threads can increment the int every .5sec -once the value is 42 the program has to print "Got it!\n" and exit. - -catch: -The threads do not know when the value is 42 - -What is a monitoring thread? - -A monitoring thread is a concept used in the philosopher's project. a monitoring thread will keep track of the int variable. If the value is 42 let the threads know to finish and exit. - -```C -#include -#include -#include -#include - -typedef struct s_data -{ - bool is_done; - pthread_mutex_t mutex_lock; -} t_data; - -void *rutine(void *ptr) -{ - t_data *data = ptr; - - while (1) - { - pthread_mutex_lock(&data->mutex_lock); - if (data->is_done) - { - printf("I am dead\n"); - pthread_mutex_unlock(&data->mutex_lock); - return (NULL); - } - pthread_mutex_unlock(&data->mutex_lock); - sleep(1); - printf("I am still alive\n"); - } - return (NULL); -} - -int main() -{ - pthread_t thread[4]; - t_data data; - - - data.is_done = false; - pthread_mutex_init(&data.mutex_lock, NULL); - for (int i = 0; i < 4; i++) - pthread_create(&thread[i], NULL, rutine, &data); - sleep(5); - pthread_mutex_lock(&data.mutex_lock); - data.is_done = true; - pthread_mutex_unlock(&data.mutex_lock); - for (int i = 0; i < 4; i++) - pthread_join(thread[i], NULL); - pthread_mutex_destroy(&data.mutex_lock); - return (0); -} -``` diff --git a/spark-sessions/philosophers/SparkSession - philosophers.md b/spark-sessions/philosophers/SparkSession - philosophers.md deleted file mode 100644 index 45280d0..0000000 --- a/spark-sessions/philosophers/SparkSession - philosophers.md +++ /dev/null @@ -1,186 +0,0 @@ -# Exercise 00 ~(20min)##### [*Really good read about threads.*](https://csc-knu.github.io/sys-prog/books/Andrew%20S.%20Tanenbaum%20-%20Modern%20Operating%20Systems.pdf#%5B%7B%22num%22%3A3419%2C%22gen%22%3A0%7D%2C%7B%22name%22%3A%22XYZ%22%7D%2C16%2C753%2C1%5D) -## Lets Talk Threads -- Why use ***threads***? ~ (5min) -- What are threads? ~ (5min) -- What are the differences between processes and threads ~ 5(min) - -# Ex 01 ~(20min) - -### Description: -Create a thread, see what it does, how it works. -### Goal to achieve: -Create a new thread that outputs this message! -```sh -$ ./ex01.out -Hi From thread. You can call me philosopher 0 -``` -#### Allowed functions: - -```printf pthread_create pthread_join``` - ---- -### what is pthread_t ~(5min) -1. What is the prototype? -### pthread_create ~ (5min) -1. What is the prototype? -2. What is `void \*(\*start_routine)(void \*)` -3. How would you pass data to the start_routine function? -4. What is the attr argument? -### pthread_join ~ (5min) -1. What is the prototype? -2. What is void \*\*value_ptr used for? - -# Ex02 ~(5min - 10min) - -Goal: - -Create 20 threads that will print the following - -```ascii -Hi From thread. You can call me philosopher 0 -Hi From thread. You can call me philosopher 0 -Hi From thread. You can call me philosopher 0 -Hi From thread. You can call me philosopher 0 -Hi From thread. You can call me philosopher 0 -Hi From thread. You can call me philosopher 0 -Hi From thread. You can call me philosopher 0 -Hi From thread. You can call me philosopher 0 -Hi From thread. You can call me philosopher 0 -Hi From thread. You can call me philosopher 0 -Hi From thread. You can call me philosopher 0 -Hi From thread. You can call me philosopher 0 -Hi From thread. You can call me philosopher 0 -Hi From thread. You can call me philosopher 0 -Hi From thread. You can call me philosopher 0 -Hi From thread. You can call me philosopher 0 -Hi From thread. You can call me philosopher 0 -Hi From thread. You can call me philosopher 0 -Hi From thread. You can call me philosopher 0 -Hi From thread. You can call me philosopher 0 -``` - -# Ex03 ~35min - -## Race conditions - -[Whatch a video about data races](https://www.youtube.com/watch?v=FY9livorrJI) - -1. What are race conditions? -2. What is a critical section? - -How to spot race conditions? - -Do you see a data race in this code? - -```C -// example code -#include -#include - -void *rutine(void *ptr) -{ - while (*(int *)ptr < 1000) - { - *(int *)ptr += 1; - } - printf("Done\n"); - return (NULL); -} - -int main() -{ - pthread_t thread; - int index; - - index = 0; - pthread_create(&thread, NULL, rutine, &index); - while (index < 10000) - { - index++; - } - pthread_join(thread, NULL); - return (0); -} -``` -### What are mutexes? - -What is the pthread_mutex_t data type? - -### pthread_mutex_init ~ 5(min) -What does this function do? - -### pthread_mutex_destroy ~ 5(min) - - What does this function do? - Do you have to free the mutex? - -### pthread_mutex_lock ~ 5 (min) - - What does this function do? - Can you lock a mutex that is not inited? - -### pthread_mutex_unlock ~ 25 (min) - - What does this function do? - What happens when u unlock a mutex 2times? - -Goal: -Make a program that inits, locks, unlock and destroys a mutex! - -Goal: -Prevent the data race in the example code. - -# ex04 - -## Deadlocks - -What is a deadlock? -When does a deadlock occur? - - -#### Goal: - -Goal: -Produce a program that has a deadlock. - -# Break - -# ex05 -creat 20 threads that will print the following -the order does not matter - -```ascii -Hi From thread. You can call me philosopher 1 -Hi From thread. You can call me philosopher 2 -Hi From thread. You can call me philosopher 3 -Hi From thread. You can call me philosopher 4 -Hi From thread. You can call me philosopher 5 -Hi From thread. You can call me philosopher 6 -Hi From thread. You can call me philosopher 7 -Hi From thread. You can call me philosopher 8 -Hi From thread. You can call me philosopher 9 -Hi From thread. You can call me philosopher 10 -Hi From thread. You can call me philosopher 11 -Hi From thread. You can call me philosopher 12 -Hi From thread. You can call me philosopher 13 -Hi From thread. You can call me philosopher 14 -Hi From thread. You can call me philosopher 15 -Hi From thread. You can call me philosopher 16 -Hi From thread. You can call me philosopher 17 -Hi From thread. You can call me philosopher 18 -Hi From thread. You can call me philosopher 19 -Hi From thread. You can call me philosopher 20 -Hi From thread. You can call me philosopher 21 -``` - -# Bonus - -Make a program that will use 3 created threads to add up an int to 42. Threads can increment the int every .5sec -once the value is 42 the program has to print "Got it!\n" and exit. - -catch: -The threads do not know when the value is 42 - -What is a monitoring thread? - -A monitoring thread is a concept used in the philosopher's project. a monitoring thread will keep track of the int variable. If the value is 42 let the threads know to finish and exit. diff --git a/spark-sessions/philosophers/SparkSession -philosophers - mod.md b/spark-sessions/philosophers/SparkSession -philosophers - mod.md new file mode 100644 index 0000000..9cc278e --- /dev/null +++ b/spark-sessions/philosophers/SparkSession -philosophers - mod.md @@ -0,0 +1,815 @@ +# Topics +1. Thr*e*ads. +2. Data rac*e*s. +3. Mut*e*x*e*s. +4. D*e*adlocks. + +# L*e*ts talk __Thr*e*ads__ +__Thr*e*ads__ are a part of proc*e*ss*e*s. Ev*e*ry proc*e*ss is built of many parts, addr*e*ss spac*e*, m*e*mory spac*e*, PID, __"thr*e*ad of *e*x*e*cution"__, *e*nvironm*e*nt, *e*tc.. In 2001 th*e* first Multicor*e* proc*e*ssors w*e*r*e* introduc*e*d, and th*e* ability to add mor*e* thr*e*ads p*e*r proc*e*ss cam*e* along. __Proc*e*ss*e*s__ do not __sh*e*ar m*e*mory space__ with oth*e*r proc*e*ss*e*s and hav*e* additional information associat*e*d with th*e*m lik*e* PID, nam*e* spac*e*, *e*tc, but __thr*e*ads__ ar*e* mor*e* lightw*e*ight and sh*e*ar m*e*mory spac*e* with oth*e*r thr*e*ads b*e*longing to th*e* sam*e* proc*e*ss. + +This is what I __m*e*an__ by that a proc*e*ss has a __thr*e*ad__. + +Screen Shot 2022-05-09 at 3 28 42 PM + +[after the session more on the same topic](https://csc-knu.github.io/sys-prog/books/Andrew%20S.%20Tanenbaum%20-%20Modern%20Operating%20Systems.pdf#page=134) + +1. What is a thr*e*ad? +##### Answer +> One way of looking at a process is that it is a way to group related resources. A process has an address space containing program text and data and other resources. These resources may include open files, child processes, pending alarms, signal handlers, accounting information, and more. By putting them together in the form of a process, they can be managed more easily. The other concept a process has is a ***thread*** of execution, usually shortened to just ***thread***. The ***thread*** has a program counter that keeps track of which instruction to execute next. It has registers, which hold its current working variables. It has a stack, which contains the execution history, with one frame for each procedure called but not yet returned from. Although a ***thread*** must execute in some process, the ***thread*** and its process are different concepts and can be treated separately. Processes are used to group resources together; ***threads*** are the entities scheduled for execution on the CPU. +2. What do*e*s it m*e*an that *e*v*e*ry proc*e*ss has a thr*e*ad? +##### Answear +> The other concept a process has is a thread of execution, usually shortened to just thread. The thread has a program counter that keeps track of which instruction to execute next + +***Program one*** uses ***fork*** to creat a new ***process***. ***Processes*** ***do not shear memory space***. + +```C +//Program one writen in pseudocode +#include +#include +#include + +int main() +{ + int x; + pid_t pid; + + x = 25; + make_process(); + child + { + printf("Child value %d\n", x++); + sleep(1); + printf("Child value %d\n", x++); + sleep(1); + printf("Child value %d\n", x++); + sleep(1); + printf("Child value %d\n", x++); + sleep(1); + } + parent + { + sleep(5); + printf("Parent value %d\n", x); + wait(0); + } + return (0); +} +``` +`gcc Program_one.c; ./a.out #what can we expect the x value to be in parent?` +##### Answer + +> Child value 25 +> +> Child value 26 +> +> Child value 27 +> +> Child value 28 +> +> Parent value 25 + +***Program two*** uses __pthr*e*ad_cr*e*at*e*__ to creat a new __thr*e*ad__. __Thr*e*ads__ do not shear __memory spac*e*__. + +```C +//Program_two writen in pseudocode +int main() +{ + int x; + + x = 25; + make_a_thread(); + thread + { + printf("new thread value %d\n", x++); + sleep(1); + printf("new thread value %d\n", x++); + sleep(1); + printf("new thread value %d\n", x++); + sleep(1); + printf("new thread value %d\n", x++); + sleep(1); + } + main thread + { + sleep(5); + printf("Main thread value %d\n", x); + } + return (0); +} +``` +`gcc Program_two.c; ./a.out #what can we expect the x value to be in parent?` + +##### Answer +> 29 + +1. What do*e*s it m*e*an to sh*e*ar __m*e*mory spac*e*__ in s*e*ns*e* of varibl*e*s? +##### Answer +> It means that you have access to the varibles for the seprate threads if you wish +2. Why is it useful to sh*e*ar __m*e*mory spac*e*__? +##### Answer +> You don't need to use pipes or signals to communicate information. + +# One a practical not*e* ๐Ÿงถ + +#### Allowed functions: + +```C +#include +#include + +int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void ), void *arg); +int pthread_join(pthread_t thread, void **value_ptr); +int printf(const char *restrict format, ...); +``` + +### pthread_t +1. What **data** type is pthread_t? +##### Answer +> It is used to store threads +2. Why us*e* pthr*e*ad_t not an __int__? +##### Answer +> int can not store all the info that a thread type needs + +### pthread_create +1. What __argum*e*nts__ do*e*s th*e* __pthr*e*ad_create__ tak*e*? + +##### Answer +> It take 3 Args. a thread mem address, a function pointer, void mem address + +2. What is void \*(\*start_routin*e*)(void \*)? + +##### Answer +> A functions pointer which returns void * and takes void * + +3. What is *e*x*e*cut*e*d wh*e*n pthr*e*ad_cr*e*at*e* is call*e*d? + +##### Answer +> start_routine + +4. How would you pass __data__ to th*e* start_routin*e* function? + +##### Answer +> You would pass it as the 4rd arg to pthread_create + +5. What is th*e* attr argum*e*nt? + +##### Answer +> attr allows you to set characteristics of a thread + +6. Why us*e* pthr*e*ad_cr*e*at*e*? + +##### Answer +> To create a thrad with in a process + +7. Why not us*e* fork in st*e*ad of pthr*e*ad_cr*e*at*e*? +##### Answer +> Because frok make a new process and pthread_create creates a new thread + +### pthread_join +1. What argum*e*nts do*e*s th*e* function tak*e*? + +##### Answer +> value of the thread, a memory address of type void pointer + +2. What is void \*\*valu*e*_ptr us*e*d for? + +##### Answer +> to get the value returned from start_routine + +3. What hpp*e*ns if you do not call __pthr*e*ad_join__ aft*e*r __pthr*e*ad_cr*e*ate__ + +##### Answer +> the main process will exit and the create thread will exit + +## Goal ๐ŸŽฏ +Cr*e*at*e* a n*e*w thr*e*ad that outputs this m*e*ssag*e*! +```sh +$ ./ex01.out +Hi From the thread. You can call me philosopher 1 +``` + +#### Answer +```C +#include +#include + +void *routine(void *ptr) +{ + printf("Hi From thread. You can call me philosopher 0\n"); + return (NULL); +} + +int main() +{ + pthread_t thread; + + pthread_create(&thread, NULL, routine, NULL); + pthread_join(thread, NULL); + return (0); +} +``` + +#### L*e*arn how to cr*e*at*e* thr*e*ads in a loop. Cr*e*at*e* 20 thr*e*ads that will print th*e* following. + +## Goal ๐ŸŽฏ +#### Achi*e*v*e* this output + +```ASCII +Hi From the thread. You can call me philosopher 1 +Hi From the thread. You can call me philosopher 1 +Hi From the thread. You can call me philosopher 1 +Hi From the thread. You can call me philosopher 1 +Hi From the thread. You can call me philosopher 1 +Hi From the thread. You can call me philosopher 1 +Hi From the thread. You can call me philosopher 1 +Hi From the thread. You can call me philosopher 1 +Hi From the thread. You can call me philosopher 1 +Hi From the thread. You can call me philosopher 1 +Hi From the thread. You can call me philosopher 1 +Hi From the thread. You can call me philosopher 1 +Hi From the thread. You can call me philosopher 1 +Hi From the thread. You can call me philosopher 1 +Hi From the thread. You can call me philosopher 1 +Hi From the thread. You can call me philosopher 1 +Hi From the thread. You can call me philosopher 1 +Hi From the thread. You can call me philosopher 1 +Hi From the thread. You can call me philosopher 1 +Hi From the thread. You can call me philosopher 1 +Hi From the thread. You can call me philosopher 1 +``` +###### Answer +```C +#include +#include + +#define MAX_PHILO 20 + +void *rutine(void *ptr) +{ + printf("Hi From thread. You can call me philosopher 0\n"); + return (NULL); +} + +int main() +{ + pthread_t thread[MAX_PHILO]; + + for (int i = 0; i < MAX_PHILO; i++) + { + pthread_create(&thread[i], NULL, rutine, NULL); + } + for (int i = 0; i < MAX_PHILO; i++) + { + pthread_join(thread[i], NULL); + } + return (0); +} +``` +## Data rac*e*s/rac*e* conditions + +[Whatch a vid*e*o about data rac*e*s till 9:10](https://www.youtube.com/watch?v=FY9livorrJI) + +1. What ar*e* __data rac*e*s?__ + +##### Answer +> A data race is when data values become unpredeictable because two or more threads are writing to the same variable. + +2. What is a __critical s*e*ction?__ + +##### Answer +> That is the segment of code where the data race is happening + +3. If two or mor*e* __thr*e*ads__ ar*e* r*e*ading th*e* valu*e* at th*e* sam*e* tim*e* is that a __data rac*e*__? + +##### Answer +> No + +4. Can th*e* compil*e*r h*e*lp spot __data rac*e*s__? + +##### Answer +> -g -fsanitize=thread + +5. Why ar*e* __data rac*e*s__ bad? + +#### Answer +> Because they lead to undefined behaviour + +##### Do you see a **data race** in this code? + +```C +// example code +#include +#include + +void rutine(void ptr) +{ + while (1) + { + if ((int )ptr > 1000) + break ; + (int )ptr += 1; + } + printf("Done\n"); + return (NULL); +} + +int main() +{ + pthread_t thread; + int index; + + index = 0; + //keep in mind that the programm "splits in 2" after this call + pthread_create(&thread, NULL, rutine, &index); + while (1) + { + if (index > 10000) + break ; + index++; + } + pthread_join(thread, NULL); + return (0); +} +``` +##### Where there a **critical section**? +#### Answer +```C + if ((int )ptr > 1000) + break ; + (int )ptr += 1; + if (index > 10000) + break ; + index++; +``` +## L*e*t's talk mut*e*x*e*s + +Th*e* solution to __data rac*e*s__ can b*e* __mut*e*x*e*s__. Wh*e*n a __mut*e*x__ is us*e*d it *e*nsur*e*s that only on*e* __thr*e*ad__ can acc*e*ss a pi*e*c*e* of cod*e* at a tim*e*. Mutual *e*xclusion. + +#### Allow*e*d functions +```C +#include + +int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void ), void *arg); +int pthread_join(pthread_t thread, void **value_ptr); +int printf(const char *restrict format, ...); +int pthread_mutex_lock(pthread_mutex_t mutex); +int pthread_mutex_unlock(pthread_mutex_t mutex); +int pthread_mutex_init(pthread_mutex_t mutex, const pthread_mutexattr_t attr); +int pthread_mutex_destroy(pthread_mutex_t mutex); +``` + +For r*e*f*e*r*e*nc*e* This is how the __pthr*e*ad_mut*e*x_t data__ typ*e* looks lik*e*. + +```C +struct _opaque_pthread_mutex_t { + long __sig; + char __opaque[__PTHREAD_MUTEX_SIZE__]; +}; +``` + +1. What is th*e* __pthr*e*ad_mut*e*x_t data__ typ*e*? + +#### Answer +> It is a data type that you can lock. + +### pthread_mutex_init +1. What does this function do? +#### Answer +> it make a mutex lockable, allocates resources for the mutex +```C +struct _opaque_pthread_mutex_t { + long __sig; //it changes this value + char __opaque[__PTHREAD_MUTEX_SIZE__]; +}; +``` + +2. Why do w*e* n*ee*d to init a mut*e*x? + +#### Answer +> because it alows for the mutex to be locked + +### pthread_mutex_destroy +1.What does this function do? +> it makes a mutex not lockable, deallocates resources for the mutex +#### Answer + +```C +struct _opaque_pthread_mutex_t { + long __sig; //it changes this to 0 + char __opaque[__PTHREAD_MUTEX_SIZE__]; +}; +``` + +2. Do you hav*e* to fr*ee* th*e* mut*e*x? +#### Answer +> No! + +3. Do you n*ee*d to d*e*stroy init*e*d mut*e*x*e*s? +#### Answer +> Yes and no, it is considered a good practice and it helps to spot bugs. It does not cause memory leaks on our systems or take up resources, I belive. + +4. Can a locked mutex be destroyed? +#### Answer +> No and errno will be set to EBUSY + +### pthread_mutex_lock +1. What does this function do? + +#### Answer +> It locks a **mutex**. No other **threads** can access this block of code. + +2. Can you lock a mut*e*x 2 tim*e*s? + +#### Answer +> No all the other threads will be waiting to for the mutex till it is onlocked. + +3. Why do w*e* n*ee*d to lock mut*e*x*e*s? +> Because we want to limit the segment of code accessible to only 1 thread hence stop data race + +### pthread_mutex_unlock +1. What does this function do? +#### Answer +> Unlocks a mutex. All threads can now access the code block. + +2. Why do w*e* n*ee*d to unlock mut*e*x*e*s? +#### Answer +> Because we want to give access to all the threads to a segment of code + +## Goal ๐ŸŽฏ +Make a program that inits, locks, unlock and destroys a mutex! + +#### Answer +```C +#include + +int main() +{ + pthread_mutex_t lock; + + pthread_mutex_init(&lock, NULL); + pthread_mutex_lock(&lock); + pthread_mutex_unlock(&lock); + pthread_mutex_destroy(&lock); + return (0); +} +``` + +## Goal ๐ŸŽฏ + +Pr*e*v*e*nt th*e* data rac*e* in th*e* *e*xampl*e* cod*e*. +```C +// example code +#include +#include + +void *rutine(void *ptr) +{ + while (1) + { + if (*(int *)ptr < 1000) + break ; + *(int *)ptr += 1; + } + printf("Done\n"); + return (NULL); +} + +int main() +{ + pthread_t thread; + int index; + + index = 0; + pthread_create(&thread, NULL, rutine, &index); + while (1) + { + if (index < 10000) + break; + index++; + } + pthread_join(thread, NULL); + return (0); +} +``` + +#### Answer +```C +#include +#include + +typedef struct s_int_lock +{ + int num; + pthread_mutex_t lock; +} t_num_lock; + +void *rutine(void *ptr) +{ + + t_num_lock *thread_safe_num; + + thread_safe_num = ptr; + while (1) + { + pthread_mutex_lock(&thread_safe_num->lock); + if (thread_safe_num->num > 1000) + { + pthread_mutex_unlock(&thread_safe_num->lock); + break ; + } + thread_safe_num->num += 1; + pthread_mutex_unlock(&thread_safe_num->lock); + } + printf("Done\n"); + return (NULL); +} + +int main() +{ + t_num_lock thread_safe_num; + pthread_t thread; + + thread_safe_num.num = 0; + pthread_mutex_init(&thread_safe_num.lock, NULL); + pthread_create(&thread, NULL, rutine, &thread_safe_num); + while (1) + { + pthread_mutex_lock(&thread_safe_num.lock); + if (thread_safe_num.num > 10000) + { + pthread_mutex_unlock(&thread_safe_num.lock); + break; + } + thread_safe_num.num++; + pthread_mutex_unlock(&thread_safe_num.lock); + } + pthread_mutex_destroy(&thread_safe_num.lock); + pthread_join(thread, NULL); + return (0); +} +``` + + +## Deadlocks + +1. What is a **deadlock**? +#### Answer +a dead lock is when the programm hangs because it tries to lock a mutex that is already lock and will never be unlocked +2. When does a **deadlock** occur? +#### Answer +when u do not unlock a mutex +## Goal: + +Produce a program that has a deadlock. + +### Answer + +```C +#include + +int main() +{ + pthread_mutex_t lock; + + pthread_mutex_init(&lock, NULL); + pthread_mutex_lock(&lock); + pthread_mutex_lock(&lock); + pthread_mutex_unlock(&lock); + pthread_mutex_destroy(&lock); + return (0); +} +``` + +## Why not use threads? +It seams that having more threads would speed things up, but it's not always the case. +Bellow, 2 programs add up to INT_MAX / 100. One uses 20 **threads** and one uses just one. Which will be faster? + +```C +#include +#include +#include +#include + +typedef struct s_list +{ + int *num; + pthread_mutex_t lock; +} t_list; + +#define MAX_PHILO 20 + +void *rutine(void *ptr) +{ + t_list *philo = ptr; + + while (1) + { + pthread_mutex_lock(&philo->lock); + if (*philo->num > INT_MAX / 100) + { + pthread_mutex_unlock(&philo->lock); + return (NULL); + } + *philo->num += 1; + pthread_mutex_unlock(&philo->lock); + } + return (NULL); +} + +int main() +{ + pthread_t thread[MAX_PHILO]; + t_list philosopher[MAX_PHILO]; + int *x = malloc(sizeof(int)); + + *x = 0; + for (int i = 0; i < 20; i++) + { + pthread_mutex_init(&philosopher[i].lock, NULL); + pthread_mutex_lock(&philosopher[i].lock); + philosopher[i].num = x; + pthread_mutex_unlock(&philosopher[i].lock); + pthread_create(&thread[i], NULL, rutine, &philosopher[i]); + } + for (int i = 0; i < MAX_PHILO; i++) + { + pthread_join(thread[i], NULL); + pthread_mutex_destroy(&philosopher[i].lock); + } + printf("%d\n", *philosopher[0].num); + free(philosopher[0].num); + return (0); +} +``` +```C +#include +#include +#include +#include + +int main() +{ + int x; + + x = 0; + while (x < INT_MAX / 100) + { + x++; + } + printf("%d\n", x); +} +``` +## Goal +compile both programms and use `time ./a.out` to see which is faster + +## Goal: +creat 20 threads that will print the following +the order does not matter + +```ASCII +Hi From the thread. You can call me philosopher 1 +Hi From the thread. You can call me philosopher 2 +Hi From the thread. You can call me philosopher 3 +Hi From the thread. You can call me philosopher 4 +Hi From the thread. You can call me philosopher 5 +Hi From the thread. You can call me philosopher 6 +Hi From the thread. You can call me philosopher 7 +Hi From the thread. You can call me philosopher 8 +Hi From the thread. You can call me philosopher 9 +Hi From the thread. You can call me philosopher 10 +Hi From the thread. You can call me philosopher 11 +Hi From the thread. You can call me philosopher 12 +Hi From the thread. You can call me philosopher 13 +Hi From the thread. You can call me philosopher 14 +Hi From the thread. You can call me philosopher 15 +Hi From the thread. You can call me philosopher 16 +Hi From the thread. You can call me philosopher 17 +Hi From the thread. You can call me philosopher 18 +Hi From the thread. You can call me philosopher 19 +Hi From the thread. You can call me philosopher 20 +Hi From the thread. You can call me philosopher 21 +``` + +##### Answer + +```C +#include +#include + +typedef struct s_list +{ + int index; + pthread_mutex_t lock; +} t_list; + +#define MAX_PHILO 20 + +void *rutine(void *ptr) +{ + pthread_mutex_lock(&((t_list *)ptr)->lock); + printf("Hi From thread. You can call me philosopher %d\n", (*(t_list *)ptr).index + 1); + pthread_mutex_unlock(&((t_list *)ptr)->lock); + return (NULL); +} + +int main() +{ + pthread_t thread[MAX_PHILO]; + t_list philosopher[MAX_PHILO]; + + for (int i = 0; i < 20; i++) + { + pthread_mutex_init(&philosopher[i].lock, NULL); + pthread_mutex_lock(&philosopher[i].lock); + philosopher[i].index = i; + pthread_mutex_unlock(&philosopher[i].lock); + pthread_create(&thread[i], NULL, rutine, &philosopher[i]); + } + for (int i = 0; i < MAX_PHILO; i++) + { + pthread_join(thread[i], NULL); + pthread_mutex_destroy(&philosopher[i].lock); + } + return (0); +} +``` + +# Bonus + +Make a program that will use 3 created threads to add up an int to 42. Threads can increment the int every .5sec +once the value is 42 the program has to print "Got it!\n" and exit. + +catch: +The threads do not know when the value is 42 + +What is a monitoring thread? + +A monitoring thread is a concept used in the philosopher's project. a monitoring thread will keep track of the int variable. If the value is 42 let the threads know to finish and exit. + +```C +#include +#include +#include +#include + +typedef struct s_data +{ + bool is_done; + pthread_mutex_t mutex_lock; +} t_data; + +void *rutine(void *ptr) +{ + t_data *data = ptr; + + while (1) + { + pthread_mutex_lock(&data->mutex_lock); + if (data->is_done) + { + printf("I am dead\n"); + pthread_mutex_unlock(&data->mutex_lock); + return (NULL); + } + pthread_mutex_unlock(&data->mutex_lock); + sleep(1); + printf("I am still alive\n"); + } + return (NULL); +} + +int main() +{ + pthread_t thread[4]; + t_data data; + + + data.is_done = false; + pthread_mutex_init(&data.mutex_lock, NULL); + for (int i = 0; i < 4; i++) + pthread_create(&thread[i], NULL, rutine, &data); + sleep(5); + pthread_mutex_lock(&data.mutex_lock); + data.is_done = true; + pthread_mutex_unlock(&data.mutex_lock); + for (int i = 0; i < 4; i++) + pthread_join(thread[i], NULL); + pthread_mutex_destroy(&data.mutex_lock); + return (0); +} +``` +# Aditional resources: +##### [*Theory on what are threads*](https://csc-knu.github.io/sys-prog/books/Andrew%20S.%20Tanenbaum%20-%20Modern%20Operating%20Systems.pdf#%5B%7B%22num%22%3A3419%2C%22gen%22%3A0%7D%2C%7B%22name%22%3A%22XYZ%22%7D%2C16%2C753%2C1%5D) +##### [*Videos with practical examples*](https://www.youtube.com/watch?v=d9s_d28yJq0&list=PLfqABt5AS4FmuQf70psXrsMLEDQXNkLq2) +Look in to what a scheduler is! + + +#### Why use **threads**? + +##### Answer +> 1. Creating a thread goes 10โ€“100 times faster than creating a process. +> 2. To shear address space +> 3. Performance +> 4. To work with blocking system calls +> 5. There is a blocking call + diff --git a/spark-sessions/philosophers/SparkSession -philosophers.md b/spark-sessions/philosophers/SparkSession -philosophers.md new file mode 100644 index 0000000..0e47046 --- /dev/null +++ b/spark-sessions/philosophers/SparkSession -philosophers.md @@ -0,0 +1,453 @@ +# writ*e* n*e*w ans*e*ar for th*e* n*e*w q*e*stions +# show to Jusa +# r*e*ad it 10 tim*e*s ov*e*r till your happy + +# Topics +1. Thr*e*ads. +2. Data rac*e*s. +3. Mut*e*x*e*s. +4. D*e*adlocks. + +# L*e*ts talk __Thr*e*ads__ +__Thr*e*ads__ are a part of proc*e*ss*e*s. Ev*e*ry proc*e*ss is built of many parts, addr*e*ss spac*e*, m*e*mory spac*e*, PID, __"thr*e*ad of *e*x*e*cution"__, *e*nvironm*e*nt, *e*tc.. In 2001 th*e* first Multicor*e* proc*e*ssors w*e*r*e* introduc*e*d, and th*e* ability to add mor*e* thr*e*ads p*e*r proc*e*ss cam*e* along. __Proc*e*ss*e*s__ do not __sh*e*ar m*e*mory space__ with oth*e*r proc*e*ss*e*s and hav*e* additional information associat*e*d with th*e*m lik*e* PID, nam*e* spac*e*, *e*tc, but __thr*e*ads__ ar*e* mor*e* lightw*e*ight and sh*e*ar m*e*mory spac*e* with oth*e*r thr*e*ads b*e*longing to th*e* sam*e* proc*e*ss. + +This is what I __m*e*an__ by that a proc*e*ss has a __thr*e*ad__. + +Screen Shot 2022-05-09 at 3 28 42 PM + +[after the session more on the same topic](https://csc-knu.github.io/sys-prog/books/Andrew%20S.%20Tanenbaum%20-%20Modern%20Operating%20Systems.pdf#page=134) + + +1. What is a thr*e*ad? +2. What do*e*s it m*e*an that *e*v*e*ry proc*e*ss has a thr*e*ad? + +***Program one*** uses ***fork*** to creat a new ***process***. ***Processes*** ***do not shear memory space***. +# chande to actual code +```C +//Program one writen in pseudocode +#include +#include +#include + +int main() +{ + int x; + pid_t pid; + + x = 25; + make_process(); + child + { + printf("Child value %d\n", x++); + sleep(1); + printf("Child value %d\n", x++); + sleep(1); + printf("Child value %d\n", x++); + sleep(1); + printf("Child value %d\n", x++); + sleep(1); + } + parent + { + sleep(5); + printf("Parent value %d\n", x); + wait(0); + } + return (0); +} +``` + +`gcc Program_one.c; ./a.out #what can we expect the x value to be in parent?` + +***Program two*** uses __pthr*e*ad_cr*e*at*e*__ to creat a new __thr*e*ad__. __Thr*e*ads__ do not shear __memory spac*e*__. + + +```C +//Program_two writen in pseudocode +int main() +{ + int x; + + x = 25; + make_a_thread(); + thread + { + printf("new thread value %d\n", x++); + sleep(1); + printf("new thread value %d\n", x++); + sleep(1); + printf("new thread value %d\n", x++); + sleep(1); + printf("new thread value %d\n", x++); + sleep(1); + } + main thread + { + sleep(5); + printf("Main thread value %d\n", x); + } + return (0); +} +``` +`gcc Program_two.c; ./a.out #what can we expect the x value to be in thread?` + +1. What do*e*s it m*e*an to sh*e*ar __m*e*mory spac*e*__ in s*e*ns*e* of varibl*e*s? +2. Why is it useful to sh*e*ar __m*e*mory spac*e*__? + +# One a practical not*e* ๐Ÿงถ + +#### Allowed functions: + +```C +#include +#include + +int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg); +int pthread_join(pthread_t thread, void **value_ptr); +int printf(const char *restrict format, ...); +``` + +### pthr*e*ad_t +1. What __data__ typ*e* is pthread_t? +2. Why us*e* pthr*e*ad_t not an __int__? + +### pthr*e*ad_cr*e*at*e* +1. What __argum*e*nts__ do*e*s th*e* __pthr*e*ad_create__ tak*e*? +2. What is void \*(\*start_routin*e*)(void \*)? +3. What is *e*x*e*cut*e*d wh*e*n pthr*e*ad_cr*e*at*e* is call*e*d? +4. How would you pass __data__ to th*e* start_routin*e* function? +5. What is th*e* attr argum*e*nt? +6. Why us*e* pthr*e*ad_cr*e*at*e*? +7. Why not us*e* fork in st*e*ad of pthr*e*ad_cr*e*at*e*? + +### pthr*e*ad_join +1. What argum*e*nts do*e*s th*e* function tak*e*? +2. What is void \*\*valu*e*_ptr us*e*d for? +3. What hpp*e*ns if you do not call __pthr*e*ad_join__ aft*e*r __pthr*e*ad_cr*e*ate__ + +## Goal ๐ŸŽฏ +Cr*e*at*e* a n*e*w thr*e*ad that outputs this m*e*ssag*e*! +```sh +$ ./ex01.out +Hi From the thread. You can call me philosopher 1 +``` + +#### L*e*arn how to cr*e*at*e* thr*e*ads in a loop. Cr*e*at*e* 20 thr*e*ads that will print th*e* following. + +## Goal ๐ŸŽฏ +#### Achi*e*v*e* this output +```ASCII +Hi From the thread. You can call me philosopher 1 +Hi From the thread. You can call me philosopher 1 +Hi From the thread. You can call me philosopher 1 +Hi From the thread. You can call me philosopher 1 +Hi From the thread. You can call me philosopher 1 +Hi From the thread. You can call me philosopher 1 +Hi From the thread. You can call me philosopher 1 +Hi From the thread. You can call me philosopher 1 +Hi From the thread. You can call me philosopher 1 +Hi From the thread. You can call me philosopher 1 +Hi From the thread. You can call me philosopher 1 +Hi From the thread. You can call me philosopher 1 +Hi From the thread. You can call me philosopher 1 +Hi From the thread. You can call me philosopher 1 +Hi From the thread. You can call me philosopher 1 +Hi From the thread. You can call me philosopher 1 +Hi From the thread. You can call me philosopher 1 +Hi From the thread. You can call me philosopher 1 +Hi From the thread. You can call me philosopher 1 +Hi From the thread. You can call me philosopher 1 +Hi From the thread. You can call me philosopher 1 +``` + +## Data rac*e*s/rac*e* conditions + +[Whatch a vid*e*o about data rac*e*s till 9:10](https://www.youtube.com/watch?v=FY9livorrJI) + +1. What ar*e* __data rac*e*s?__ +2. What is a __critical s*e*ction?__ +3. If two or mor*e* __thr*e*ads__ ar*e* r*e*ading th*e* valu*e* at th*e* sam*e* tim*e* is that a __data rac*e*__? +4. Can th*e* compil*e*r h*e*lp spot __data rac*e*s__? +5. Why ar*e* __data rac*e*s__ bad? + +##### Do you s*ee* a __data rac*e*__ in this cod*e*? + +```C +// example code +#include +#include + +void rutine(void ptr) +{ + while (1) + { + if ((int )ptr > 1000) + break ; + (int )ptr += 1; + } + printf("Done\n"); + return (NULL); +} + +int main() +{ + pthread_t thread; + int index; + + index = 0; + //keep in mind that the programm "splits in 2" after this call + pthread_create(&thread, NULL, rutine, &index); + while (1) + { + if (index > 10000) + break ; + index++; + } + pthread_join(thread, NULL); + return (0); +} +``` + +##### Wh*e*r*e* is th*e*r*e* a __critical s*e*ction__? + +## L*e*t's talk mut*e*x*e*s +Th*e* solution to __data rac*e*s__ can b*e* __mut*e*x*e*s__. Wh*e*n a __mut*e*x__ is us*e*d it *e*nsur*e*s that only on*e* __thr*e*ad__ can acc*e*ss a pi*e*c*e* of cod*e* at a tim*e*. Mutual *e*xclusion. + +#### Allow*e*d functions +```C +#include + +int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void ), void *arg); +int pthread_join(pthread_t thread, void **value_ptr); +int printf(const char *restrict format, ...); +int pthread_mutex_lock(pthread_mutex_t mutex); +int pthread_mutex_unlock(pthread_mutex_t mutex); +int pthread_mutex_init(pthread_mutex_t mutex, const pthread_mutexattr_t attr); +int pthread_mutex_destroy(pthread_mutex_t mutex); +``` + +For r*e*f*e*r*e*nc*e* This is how the __pthr*e*ad_mut*e*x_t data__ typ*e* looks lik*e*. + +```C +struct _opaque_pthread_mutex_t { + long __sig; + char __opaque[__PTHREAD_MUTEX_SIZE__]; +}; +``` + +1. What is th*e* __pthr*e*ad_mut*e*x_t data__ typ*e*? + +### pthr*e*ad_mut*e*x_init +1. What do*e*s this function do? +2. Why do w*e* n*ee*d to init a mut*e*x? + +### pthr*e*ad_mut*e*x_d*e*stroy +1. What do*e*s this function do? +2. Do you hav*e* to fr*ee* th*e* mut*e*x? +3. Do you n*ee*d to d*e*stroy init*e*d mut*e*x*e*s? +4. Can a locked mutex be destroyed? + +### pthr*e*ad_mut*e*x_lock +1. What do*e*s this function do? +2. Can you lock a mut*e*x 2 tim*e*s? + +### pthr*e*ad_mut*e*x_unlock +1. What do*e*s this function do? + +## Goal ๐ŸŽฏ + +Mak*e* a program that inits, locks, unlock and d*e*stroys a mut*e*x! + +## Goal ๐ŸŽฏ + +Pr*e*v*e*nt th*e* data rac*e* in th*e* *e*xampl*e* cod*e*. +```C +// example code +#include +#include + +void rutine(void ptr) +{ + while (1) + { + if ((int )ptr < 1000) + break ; + (int )ptr += 1; + } + printf("Done\n"); + return (NULL); +} + +int main() +{ + pthread_t thread; + int index; + + index = 0; + pthread_create(&thread, NULL, rutine, &index); + while (1) + { + if (index < 10000) + break; + index++; + } + pthread_join(thread, NULL); + return (0); +} +``` + +## D*e*adlocks +Deadlock is a state in a programm where all the available mutexes have been locked, thou more and more threads are trying to lock more mutexes in result the programm hangs. +1. What is a __d*e*adlock__? +2. Wh*e*n do*e*s a __d*e*adlock__ occur? + +## Goal ๐ŸŽฏ + +Produc*e* a program that has a __d*e*adlock__. + +## Why not us*e* thr*e*ads? + +It s*e*ams that having mor*e* thr*e*ads would sp*ee*d things up, but it's not always th*e* cas*e*. +B*e*llow, 2 programs add up to INT_MAX / 100. On*e* us*e*s 20 __thr*e*ads__ and on*e* us*e*s just on*e*. Which will b*e* fast*e*r? + +```C +#include +#include +#include +#include + +typedef struct s_list +{ + int num; + pthread_mutex_t lock; +} t_list; + +#define MAX_PHILO 20 + +void rutine(void ptr) +{ + t_list philo = ptr; + + while (1) + { + pthread_mutex_lock(&philo->lock); + if (philo->num > INT_MAX / 100) + { + pthread_mutex_unlock(&philo->lock); + return (NULL); + } + philo->num += 1; + pthread_mutex_unlock(&philo->lock); + } + return (NULL); +} + +int main() +{ + pthread_t thread[MAX_PHILO]; + t_list philosopher[MAX_PHILO]; + int x = malloc(sizeof(int)); + + x = 0; + for (int i = 0; i < 20; i++) + { + pthread_mutex_init(&philosopher[i].lock, NULL); + pthread_mutex_lock(&philosopher[i].lock); + philosopher[i].num = x; + pthread_mutex_unlock(&philosopher[i].lock); + pthread_create(&thread[i], NULL, rutine, &philosopher[i]); + } + for (int i = 0; i < MAX_PHILO; i++) + { + pthread_join(thread[i], NULL); + pthread_mutex_destroy(&philosopher[i].lock); + } + printf("%d\n", philosopher[0].num); + free(philosopher[0].num); + return (0); +} +``` +```C +#include +#include +#include +#include + +int main() +{ + int x; + + x = 0; + while (x < INT_MAX / 100) + { + x++; + } + printf("%d\n", x); +} +``` + +## Goal ๐ŸŽฏ +compil*e* both programms and us*e* `time ./a.out` to s*ee* which is fast*e*r + +#### Allow*e*d functions + +```C +#include +#include + +int pthread_mutex_lock(pthread_mutex_t mutex); +int pthread_mutex_unlock(pthread_mutex_t mutex); +int pthread_mutex_init(pthread_mutex_t mutex, const pthread_mutexattr_t attr); +int pthread_mutex_destroy(pthread_mutex_t mutex); +int pthread_create(pthread_t thread, const pthread_attr_t attr, void (start_routine)(void ), void arg); +int pthread_join(pthread_t thread, void value_ptr); +int printf(const char restrict format, ...); +``` + +## Goal ๐ŸŽฏ +cr*e*at 20 thr*e*ads that will print th*e* following +th*e* ord*e*r do*e*s not matt*e*r + +```ASCII +Hi From the thread. You can call me philosopher 1 +Hi From the thread. You can call me philosopher 2 +Hi From the thread. You can call me philosopher 3 +Hi From the thread. You can call me philosopher 4 +Hi From the thread. You can call me philosopher 5 +Hi From the thread. You can call me philosopher 6 +Hi From the thread. You can call me philosopher 7 +Hi From the thread. You can call me philosopher 8 +Hi From the thread. You can call me philosopher 9 +Hi From the thread. You can call me philosopher 10 +Hi From the thread. You can call me philosopher 11 +Hi From the thread. You can call me philosopher 12 +Hi From the thread. You can call me philosopher 13 +Hi From the thread. You can call me philosopher 14 +Hi From the thread. You can call me philosopher 15 +Hi From the thread. You can call me philosopher 16 +Hi From the thread. You can call me philosopher 17 +Hi From the thread. You can call me philosopher 18 +Hi From the thread. You can call me philosopher 19 +Hi From the thread. You can call me philosopher 20 +Hi From the thread. You can call me philosopher 21 +``` + +# Bonus + +Mak*e* a program that will us*e* 3 cr*e*at*e*d thr*e*ads to add up an int to 42. Thr*e*ads can incr*e*m*e*nt th*e* int *e*v*e*ry .5s*e*c +onc*e* th*e* valu*e* is 42 th*e* program has to print "Got it!\n" and *e*xit. + +catch: +Th*e* thr*e*ads do not know wh*e*n th*e* valu*e* is 42 + +What is a monitoring thr*e*ad? + +A monitoring thr*e*ad is a conc*e*pt us*e*d in th*e* philosoph*e*r's proj*e*ct. a monitoring thr*e*ad will k*ee*p track of th*e* int variabl*e*. If th*e* valu*e* is 42 l*e*t th*e* thr*e*ads know to finish and *e*xit. + + +# Aditional r*e*sourc*e*s: +##### [*Th*e*ory on what ar*e* thr*e*ads*](https://csc-knu.github.io/sys-prog/books/Andrew%20S.%20Tanenbaum%20-%20Modern%20Operating%20Systems.pdf#%5B%7B%22num%22%3A3419%2C%22gen%22%3A0%7D%2C%7B%22nam*e*%22%3A%22XYZ%22%7D%2C16%2C753%2C1%5D) +##### [*Vid*e*os with practical *e*xampl*e*s*](https://www.youtube.com/watch?v=d9s_d28yJq0&list=PLfqABt5AS4FmuQf70psXrsMLEDQXNkLq2) +Look in to what a sch*e*dul*e*r is! + + From 2fa2f3af176ca9a7231b9b87bbcba585e81b3648 Mon Sep 17 00:00:00 2001 From: Aleksandrs Date: Sat, 28 May 2022 00:42:23 +0200 Subject: [PATCH 5/6] added the new spark session --- .../SparkSession -philosophers - mod.md | 411 ++++++++++++------ .../SparkSession -philosophers.md | 395 +++++++++++------ 2 files changed, 538 insertions(+), 268 deletions(-) diff --git a/spark-sessions/philosophers/SparkSession -philosophers - mod.md b/spark-sessions/philosophers/SparkSession -philosophers - mod.md index 9cc278e..cbf3132 100644 --- a/spark-sessions/philosophers/SparkSession -philosophers - mod.md +++ b/spark-sessions/philosophers/SparkSession -philosophers - mod.md @@ -1,29 +1,30 @@ # Topics -1. Thr*e*ads. -2. Data rac*e*s. -3. Mut*e*x*e*s. -4. D*e*adlocks. +1. Threads. +2. Data Races. +3. Mutexes. +4. Deadlocks. -# L*e*ts talk __Thr*e*ads__ -__Thr*e*ads__ are a part of proc*e*ss*e*s. Ev*e*ry proc*e*ss is built of many parts, addr*e*ss spac*e*, m*e*mory spac*e*, PID, __"thr*e*ad of *e*x*e*cution"__, *e*nvironm*e*nt, *e*tc.. In 2001 th*e* first Multicor*e* proc*e*ssors w*e*r*e* introduc*e*d, and th*e* ability to add mor*e* thr*e*ads p*e*r proc*e*ss cam*e* along. __Proc*e*ss*e*s__ do not __sh*e*ar m*e*mory space__ with oth*e*r proc*e*ss*e*s and hav*e* additional information associat*e*d with th*e*m lik*e* PID, nam*e* spac*e*, *e*tc, but __thr*e*ads__ ar*e* mor*e* lightw*e*ight and sh*e*ar m*e*mory spac*e* with oth*e*r thr*e*ads b*e*longing to th*e* sam*e* proc*e*ss. +# Lets talk __Threads__ +__Threads__ are a part of processes. Every processes is built of many parts, address space, memory space, PID, __"Thread of execution"__, enviorment, etc.. In 2001 the first Multicore processesors were introduced and the ability to add more Threads per processes came along. __processes__ do not __share memory space__ with other processes and have additional information associated with them like PID, name space, etc, but __Threads__ are more lightweight and share memory space with other Threads belonging to the same processes. -This is what I __m*e*an__ by that a proc*e*ss has a __thr*e*ad__. +This is what I __mean__ by that a processes has a __Thread__. Screen Shot 2022-05-09 at 3 28 42 PM [after the session more on the same topic](https://csc-knu.github.io/sys-prog/books/Andrew%20S.%20Tanenbaum%20-%20Modern%20Operating%20Systems.pdf#page=134) +##### Can you answear these qestions? +1. What is a Thread? -1. What is a thr*e*ad? ##### Answer > One way of looking at a process is that it is a way to group related resources. A process has an address space containing program text and data and other resources. These resources may include open files, child processes, pending alarms, signal handlers, accounting information, and more. By putting them together in the form of a process, they can be managed more easily. The other concept a process has is a ***thread*** of execution, usually shortened to just ***thread***. The ***thread*** has a program counter that keeps track of which instruction to execute next. It has registers, which hold its current working variables. It has a stack, which contains the execution history, with one frame for each procedure called but not yet returned from. Although a ***thread*** must execute in some process, the ***thread*** and its process are different concepts and can be treated separately. Processes are used to group resources together; ***threads*** are the entities scheduled for execution on the CPU. -2. What do*e*s it m*e*an that *e*v*e*ry proc*e*ss has a thr*e*ad? +2. What does it mean that every processes has a Thread? + ##### Answear > The other concept a process has is a thread of execution, usually shortened to just thread. The thread has a program counter that keeps track of which instruction to execute next -***Program one*** uses ***fork*** to creat a new ***process***. ***Processes*** ***do not shear memory space***. +***Program one*** uses `fork()` to creat a new ***process***. ***Processes*** ***do not shear memory space***. ```C -//Program one writen in pseudocode #include #include #include @@ -34,27 +35,23 @@ int main() pid_t pid; x = 25; - make_process(); - child + pid = fork(); + if (pid == 0)//child process { printf("Child value %d\n", x++); - sleep(1); printf("Child value %d\n", x++); - sleep(1); printf("Child value %d\n", x++); - sleep(1); printf("Child value %d\n", x++); - sleep(1); } - parent + else { - sleep(5); - printf("Parent value %d\n", x); - wait(0); + pid = wait(0); + printf("Parent value %d\n", x); } return (0); } ``` + `gcc Program_one.c; ./a.out #what can we expect the x value to be in parent?` ##### Answer @@ -68,48 +65,59 @@ int main() > > Parent value 25 -***Program two*** uses __pthr*e*ad_cr*e*at*e*__ to creat a new __thr*e*ad__. __Thr*e*ads__ do not shear __memory spac*e*__. +***Program two*** uses `pthread_create` to creat a new __Thread__. __Threads__ do not share __memory space__. ```C -//Program_two writen in pseudocode +#include +#include + +void *rutine(void *x) +{ + //2nd thread + printf("new thread value %d\n", *(int*)x); + *(int*)x += 1; + printf("new thread value %d\n", *(int*)x); + *(int*)x += 1; + printf("new thread value %d\n", *(int*)x); + *(int*)x += 1; + printf("new thread value %d\n", *(int*)x); + *(int*)x += 1; + return (NULL); +} + int main() { - int x; + int x; + pthread_t thread; - x = 25; - make_a_thread(); - thread - { - printf("new thread value %d\n", x++); - sleep(1); - printf("new thread value %d\n", x++); - sleep(1); - printf("new thread value %d\n", x++); - sleep(1); - printf("new thread value %d\n", x++); - sleep(1); - } - main thread - { - sleep(5); - printf("Main thread value %d\n", x); - } - return (0); + x = 25; + pthread_create(&thread, NULL, rutine, &x); + //main thread + pthread_join(thread, NULL); + printf("Main thread value %d\n", x); + return (0); } ``` -`gcc Program_two.c; ./a.out #what can we expect the x value to be in parent?` - +`gcc Program_two.c; ./a.out #what can we expect the x value to be in thread?` ##### Answer -> 29 - -1. What do*e*s it m*e*an to sh*e*ar __m*e*mory spac*e*__ in s*e*ns*e* of varibl*e*s? +> new thread value 25 +> +> new thread value 26 +> +> new thread value 27 +> +> new thread value 28 +> +> Main thread value 25 +##### Can you answear these qestions: +1. What does it mean to share __memory space__ in sense of varibles? ##### Answer > It means that you have access to the varibles for the seprate threads if you wish -2. Why is it useful to sh*e*ar __m*e*mory spac*e*__? +2. Why is it useful to share __memory space__? ##### Answer > You don't need to use pipes or signals to communicate information. -# One a practical not*e* ๐Ÿงถ +# One a practical note ๐Ÿงถ #### Allowed functions: @@ -117,72 +125,128 @@ int main() #include #include -int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void ), void *arg); +int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg); int pthread_join(pthread_t thread, void **value_ptr); int printf(const char *restrict format, ...); ``` -### pthread_t -1. What **data** type is pthread_t? +### `pthread_t` +`pthread_t` is a data type used to store Thread information. Maybe you have seen `pid_t` data type before? Then this is kind of simillar but in stead of process id which `pid_t` stores we store Thread info. + +##### Can you answear these qestions: + +1. What **data** type is `pthread_t`? ##### Answer > It is used to store threads -2. Why us*e* pthr*e*ad_t not an __int__? +2. Why use `pthread_t` and not an __int__? ##### Answer -> int can not store all the info that a thread type needs +> int cannot store all the info that a thread type needs. + +### `pthread_create` + +##### Explination: +Just as it sounds `pthread_create` will make a new thread! Its super similar to `fork` but it makes a new proccess in stead of a thread. + +##### Example: +```C +#include -### pthread_create -1. What __argum*e*nts__ do*e*s th*e* __pthr*e*ad_create__ tak*e*? +void *rutine(void *ptr) +{ + (void)ptr; + return (NULL); +} + +int main() +{ + pthread_t thread; + + pthread_create(&thread, NULL, rutine, 0); + return (0); +} +``` + +##### Can you answear these qestions: + +1. What __arguments__ does the `pthread_create` take? ##### Answer -> It take 3 Args. a thread mem address, a function pointer, void mem address +> It take 3 Args. a thread mem address, a function pointer and a void mem address -2. What is void \*(\*start_routin*e*)(void \*)? +2. What is void `*(*start_routine)(void *)`? ##### Answer -> A functions pointer which returns void * and takes void * +> A functions pointer which returns `void *` and takes `void *` -3. What is *e*x*e*cut*e*d wh*e*n pthr*e*ad_cr*e*at*e* is call*e*d? +3. What is executed when `pthread_create` is called? ##### Answer > start_routine -4. How would you pass __data__ to th*e* start_routin*e* function? +4. How would you pass __data__ to the `start_routine` function? ##### Answer > You would pass it as the 4rd arg to pthread_create -5. What is th*e* attr argum*e*nt? +5. What is the `attr` argument? ##### Answer > attr allows you to set characteristics of a thread -6. Why us*e* pthr*e*ad_cr*e*at*e*? +6. Why use `pthread_create`? ##### Answer -> To create a thrad with in a process +> To create a Thread with in a process + +7. Why not use `fork` in stead of `pthread_create`? -7. Why not us*e* fork in st*e*ad of pthr*e*ad_cr*e*at*e*? ##### Answer -> Because frok make a new process and pthread_create creates a new thread +> Because fork make a new process and pthread_create creates a new thread + +### `pthread_join` + +Explination: +Just as it sounds `pthread_join` will join a thread to the main thread! +[threads are a little bit like jarn](https://www.youtube.com/watch?v=uA8X5zNOGw8&t=240s) -### pthread_join -1. What argum*e*nts do*e*s th*e* function tak*e*? +##### Example: +```C +#include + +void *rutine(void *ptr) +{ + (void)ptr; + return (NULL); +} + +int main() +{ + pthread_t thread; + + pthread_create(&thread, NULL, rutine, 0); + pthread_join(thread, NULL); + return (0); +} +``` +##### Can you answear these qestions: + +1. What arguments does the function take? ##### Answer > value of the thread, a memory address of type void pointer -2. What is void \*\*valu*e*_ptr us*e*d for? +2. What is `void **value_ptr` used for? ##### Answer > to get the value returned from start_routine -3. What hpp*e*ns if you do not call __pthr*e*ad_join__ aft*e*r __pthr*e*ad_cr*e*ate__ +3. What hppens if you do not call `pthread_join` after `pthread_create` ##### Answer > the main process will exit and the create thread will exit ## Goal ๐ŸŽฏ -Cr*e*at*e* a n*e*w thr*e*ad that outputs this m*e*ssag*e*! +Create a new Thread that outputs this message! ```sh $ ./ex01.out Hi From the thread. You can call me philosopher 1 @@ -209,10 +273,10 @@ int main() } ``` -#### L*e*arn how to cr*e*at*e* thr*e*ads in a loop. Cr*e*at*e* 20 thr*e*ads that will print th*e* following. +#### Learn how to create Threads in a loop. Create 20 Threads that will print the following. -## Goal ๐ŸŽฏ -#### Achi*e*v*e* this output +## Can you code this? ๐ŸŽฏ +#### Achieve this output ```ASCII Hi From the thread. You can call me philosopher 1 @@ -265,37 +329,37 @@ int main() return (0); } ``` -## Data rac*e*s/rac*e* conditions +## Data Races/race conditions + +[Whatch a video about data Races till 9:10](https://www.youtube.com/watch?v=FY9livorrJI) -[Whatch a vid*e*o about data rac*e*s till 9:10](https://www.youtube.com/watch?v=FY9livorrJI) +##### Can you answear these qestions: -1. What ar*e* __data rac*e*s?__ +1. What are __data Races?__ ##### Answer -> A data race is when data values become unpredeictable because two or more threads are writing to the same variable. +> A data race is when data values become unpredictable because two or more threads are writing to the same variable. -2. What is a __critical s*e*ction?__ +2. What is a __critical section?__ ##### Answer > That is the segment of code where the data race is happening -3. If two or mor*e* __thr*e*ads__ ar*e* r*e*ading th*e* valu*e* at th*e* sam*e* tim*e* is that a __data rac*e*__? +3. If two or more __Threads__ are reading the value at the same time is that a __data race__? ##### Answer > No -4. Can th*e* compil*e*r h*e*lp spot __data rac*e*s__? +4. Can the compiler help spot __data Races__? ##### Answer > -g -fsanitize=thread -5. Why ar*e* __data rac*e*s__ bad? +5. Why are __data Races__ bad? #### Answer > Because they lead to undefined behaviour -##### Do you see a **data race** in this code? - ```C // example code #include @@ -331,7 +395,10 @@ int main() return (0); } ``` -##### Where there a **critical section**? +##### Can you answer thes qestions: +1. Do you see a *data race* in this code? +2. Where there a **critical section**? + #### Answer ```C if ((int )ptr > 1000) @@ -341,11 +408,11 @@ int main() break ; index++; ``` -## L*e*t's talk mut*e*x*e*s +## Let's talk Mutexes -Th*e* solution to __data rac*e*s__ can b*e* __mut*e*x*e*s__. Wh*e*n a __mut*e*x__ is us*e*d it *e*nsur*e*s that only on*e* __thr*e*ad__ can acc*e*ss a pi*e*c*e* of cod*e* at a tim*e*. Mutual *e*xclusion. +The solution to __data Races__ can be __Mutexes__. When a __mutex__ is used it ensures that only one __Thread__ can access a piece of code at a time. Mutual exclusion. -#### Allow*e*d functions +#### Allowed functions ```C #include @@ -358,85 +425,151 @@ int pthread_mutex_init(pthread_mutex_t mutex, const pthread_mutexattr_t attr); int pthread_mutex_destroy(pthread_mutex_t mutex); ``` -For r*e*f*e*r*e*nc*e* This is how the __pthr*e*ad_mut*e*x_t data__ typ*e* looks lik*e*. +For reference This is how the `pthread_mutex_t` __data__ type looks like. ```C struct _opaque_pthread_mutex_t { long __sig; - char __opaque[__PTHREAD_MUTEX_SIZE__]; + char __opaque[__PTHREAD_mutex_SIZE__]; }; ``` -1. What is th*e* __pthr*e*ad_mut*e*x_t data__ typ*e*? +1. What is the `pthread_mutex_t` __data__ type? #### Answer > It is a data type that you can lock. -### pthread_mutex_init +### `pthread_mutex_init` +##### Explination: +Just as the name suggest `pthread_mutex_init` will initialize a mutex. +##### Example: +```C +#include + +int main() +{ + pthread_mutex_t mutex; + + pthread_mutex_init(&mutex, NULL); + return (0); +} +``` +##### Can you answer these qestions? 1. What does this function do? #### Answer -> it make a mutex lockable, allocates resources for the mutex +> it make a Mutex lockable, allocates resources for the Mutex ```C struct _opaque_pthread_mutex_t { long __sig; //it changes this value - char __opaque[__PTHREAD_MUTEX_SIZE__]; + char __opaque[__PTHREAD_mutex_SIZE__]; }; ``` -2. Why do w*e* n*ee*d to init a mut*e*x? +2. Why do we need to init a mutex? #### Answer -> because it alows for the mutex to be locked +> because it alows for the Mutex to be locked + +### `pthread_mutex_destroy` +Explination: +Just as the name suggest `pthread_mutex_destroy` will destroy a mutex. +##### Example: -### pthread_mutex_destroy -1.What does this function do? -> it makes a mutex not lockable, deallocates resources for the mutex +```C +#include + +int main() +{ + pthread_mutex_t mutex; + + pthread_mutex_destroy(&mutex); + return (0); +} +``` +##### Can you answer these qestions? + +1. What does this function do? +> it makes a Mutex not lockable, deallocates resources for the Mutex #### Answer ```C struct _opaque_pthread_mutex_t { long __sig; //it changes this to 0 - char __opaque[__PTHREAD_MUTEX_SIZE__]; + char __opaque[__PTHREAD_mutex_SIZE__]; }; ``` -2. Do you hav*e* to fr*ee* th*e* mut*e*x? +2. Do you have to `free` the mutex? #### Answer > No! -3. Do you n*ee*d to d*e*stroy init*e*d mut*e*x*e*s? +3. Do you need to destroy inited mutexes? #### Answer -> Yes and no, it is considered a good practice and it helps to spot bugs. It does not cause memory leaks on our systems or take up resources, I belive. +> Yes and no, it is considered a good practice and it helps to spot bugs. It does not cause memory leaks on our systems or take up resources, I believe./*it does however, make the program stop in the wrong way, its why we join and then destroy* 4. Can a locked mutex be destroyed? #### Answer > No and errno will be set to EBUSY -### pthread_mutex_lock +### `pthread_mutex_lock` +##### Explination: +Just as the name suggest `pthread_mutex_lock` will do the magic of fixing the data race. +##### Example: +```C +#include + +int main() +{ + pthread_mutex_t mutex; + + pthread_mutex_lock(&mutex); + return (0); +} +``` +##### Can you answer these qestions: + 1. What does this function do? #### Answer -> It locks a **mutex**. No other **threads** can access this block of code. +> It locks a *mutex**. No other **threads** can access this block of code. -2. Can you lock a mut*e*x 2 tim*e*s? +2. Can you lock a mutex 2 times? #### Answer -> No all the other threads will be waiting to for the mutex till it is onlocked. +> No all the other threads will be waiting to for the Mutex till it is unlocked. + +3. Why do we need to lock Mutexes? +> Because we want to limit the segment of code accessible to only 1 thread hence stop data race. +/* we don't want to have a variable be used by two threads at the same time, due to a problem caused in the memory. when we have two thread and both use a variable and for example increase both of them. them instead of having done two increases, you isntead have done one increase"*/ + +### `pthread_mutex_unlock` +##### Explination: +Just as the name suggest `pthread_mutex_unlock`, will unlock a thread making the lock unlocked means that other threads will be able to lock it so that other threads will be able to prevent data races! +##### Example: +```C +#include + +int main() +{ + pthread_mutex_t mutex; + + pthread_mutex_unlock(&mutex); + return (0); +} +``` -3. Why do w*e* n*ee*d to lock mut*e*x*e*s? -> Because we want to limit the segment of code accessible to only 1 thread hence stop data race +##### Can you answer these qestions: -### pthread_mutex_unlock 1. What does this function do? #### Answer -> Unlocks a mutex. All threads can now access the code block. +> Unlocks a Mutex. All threads can now access the code block. -2. Why do w*e* n*ee*d to unlock mut*e*x*e*s? +2. Why do we need to unlock Mutexes? #### Answer > Because we want to give access to all the threads to a segment of code -## Goal ๐ŸŽฏ -Make a program that inits, locks, unlock and destroys a mutex! +## Can you code this? ๐ŸŽฏ +Make a program that inits, locks, unlock and destroys a Mutex! #### Answer ```C @@ -454,9 +587,9 @@ int main() } ``` -## Goal ๐ŸŽฏ +## Can you code this? ๐ŸŽฏ -Pr*e*v*e*nt th*e* data rac*e* in th*e* *e*xampl*e* cod*e*. +Prevent the data race in the example code. ```C // example code #include @@ -551,16 +684,22 @@ int main() ## Deadlocks +##### Explination: +Deadlock is a state in a programm where all the available mutexes have been locked, thou more and more threads are trying to lock more mutexes in result the programm hangs. -1. What is a **deadlock**? +##### Can you answer these qestions? + +1. What is a **Deadlock**? #### Answer -a dead lock is when the programm hangs because it tries to lock a mutex that is already lock and will never be unlocked -2. When does a **deadlock** occur? +> A Deadlock is when the programm hangs because it tries to lock a Mutex that is already lock and will never be unlocked. +2. When does a **Deadlock** occur? #### Answer -when u do not unlock a mutex +> when u do not unlock a Mutex /* in principle, you have a wiating list of people waiting for the mutex to open. so the program will wait endlessly until > > the mutex is unlocked. it is not like it checks if its available, it waits until its available*/ ## Goal: -Produce a program that has a deadlock. +## Can you code this? ๐ŸŽฏ + +Produce a program that has a Deadlock. ### Answer @@ -581,7 +720,7 @@ int main() ``` ## Why not use threads? -It seams that having more threads would speed things up, but it's not always the case. +It seems that having more threads would speed things up, but it's not always the case. Bellow, 2 programs add up to INT_MAX / 100. One uses 20 **threads** and one uses just one. Which will be faster? ```C @@ -659,10 +798,26 @@ int main() printf("%d\n", x); } ``` -## Goal + +## Can you code this? ๐ŸŽฏ compile both programms and use `time ./a.out` to see which is faster -## Goal: +#### Allowed functions + +```C +#include +#include + +int pthread_mutex_lock(pthread_mutex_t mutex); +int pthread_mutex_unlock(pthread_mutex_t mutex); +int pthread_mutex_init(pthread_mutex_t mutex, const pthread_mutexattr_t attr); +int pthread_mutex_destroy(pthread_mutex_t mutex); +int pthread_create(pthread_t thread, const pthread_attr_t attr, void (start_routine)(void ), void arg); +int pthread_join(pthread_t thread, void value_ptr); +int printf(const char restrict format, ...); +``` + +## Can you code this? ๐ŸŽฏ creat 20 threads that will print the following the order does not matter @@ -736,7 +891,7 @@ int main() # Bonus -Make a program that will use 3 created threads to add up an int to 42. Threads can increment the int every .5sec +Make a program that will use 3 created threads to add up an int to 42. Threads can increment the int every .5 sec once the value is 42 the program has to print "Got it!\n" and exit. catch: @@ -808,8 +963,8 @@ Look in to what a scheduler is! ##### Answer > 1. Creating a thread goes 10โ€“100 times faster than creating a process. -> 2. To shear address space +> 2. To share address space > 3. Performance > 4. To work with blocking system calls > 5. There is a blocking call - +/* to put less strain on the process when you have to perform multiple calculations at the same time. imagine you make a game and for each frame you need to check 100 things. instead of making one process that go's through all of it. you make 100 threads that do them seperatly. because Threads share memory, its the perfect tool to speed up your program, its also perfect because you cna constantly check when things go wrong, instead of having to wait until the end.*/ diff --git a/spark-sessions/philosophers/SparkSession -philosophers.md b/spark-sessions/philosophers/SparkSession -philosophers.md index 0e47046..8a344a4 100644 --- a/spark-sessions/philosophers/SparkSession -philosophers.md +++ b/spark-sessions/philosophers/SparkSession -philosophers.md @@ -1,30 +1,24 @@ -# writ*e* n*e*w ans*e*ar for th*e* n*e*w q*e*stions -# show to Jusa -# r*e*ad it 10 tim*e*s ov*e*r till your happy - # Topics -1. Thr*e*ads. -2. Data rac*e*s. -3. Mut*e*x*e*s. -4. D*e*adlocks. +1. Threads. +2. Data Races. +3. Mutexes. +4. Deadlocks. -# L*e*ts talk __Thr*e*ads__ -__Thr*e*ads__ are a part of proc*e*ss*e*s. Ev*e*ry proc*e*ss is built of many parts, addr*e*ss spac*e*, m*e*mory spac*e*, PID, __"thr*e*ad of *e*x*e*cution"__, *e*nvironm*e*nt, *e*tc.. In 2001 th*e* first Multicor*e* proc*e*ssors w*e*r*e* introduc*e*d, and th*e* ability to add mor*e* thr*e*ads p*e*r proc*e*ss cam*e* along. __Proc*e*ss*e*s__ do not __sh*e*ar m*e*mory space__ with oth*e*r proc*e*ss*e*s and hav*e* additional information associat*e*d with th*e*m lik*e* PID, nam*e* spac*e*, *e*tc, but __thr*e*ads__ ar*e* mor*e* lightw*e*ight and sh*e*ar m*e*mory spac*e* with oth*e*r thr*e*ads b*e*longing to th*e* sam*e* proc*e*ss. +# Lets talk __Threads__ +__Threads__ are a part of processes. Every processes is built of many parts, address space, memory space, PID, __"Thread of execution"__, enviorment, etc.. In 2001 the first Multicore processesors were introduced and the ability to add more Threads per processes came along. __processes__ do not __share memory space__ with other processes and have additional information associated with them like PID, name space, etc, but __Threads__ are more lightweight and share memory space with other Threads belonging to the same processes. -This is what I __m*e*an__ by that a proc*e*ss has a __thr*e*ad__. +This is what I __mean__ by that a processes has a __Thread__. Screen Shot 2022-05-09 at 3 28 42 PM [after the session more on the same topic](https://csc-knu.github.io/sys-prog/books/Andrew%20S.%20Tanenbaum%20-%20Modern%20Operating%20Systems.pdf#page=134) +##### Can you answear these qestions? +1. What is a Thread? +2. What does it mean that every processes has a Thread? +***Program one*** uses `fork()` to creat a new ***process***. ***Processes*** ***do not shear memory space***. -1. What is a thr*e*ad? -2. What do*e*s it m*e*an that *e*v*e*ry proc*e*ss has a thr*e*ad? - -***Program one*** uses ***fork*** to creat a new ***process***. ***Processes*** ***do not shear memory space***. -# chande to actual code ```C -//Program one writen in pseudocode #include #include #include @@ -35,23 +29,18 @@ int main() pid_t pid; x = 25; - make_process(); - child + pid = fork(); + if (pid == 0)//child process { printf("Child value %d\n", x++); - sleep(1); printf("Child value %d\n", x++); - sleep(1); printf("Child value %d\n", x++); - sleep(1); printf("Child value %d\n", x++); - sleep(1); } - parent + else { - sleep(5); - printf("Parent value %d\n", x); - wait(0); + pid = wait(0); + printf("Parent value %d\n", x); } return (0); } @@ -59,42 +48,45 @@ int main() `gcc Program_one.c; ./a.out #what can we expect the x value to be in parent?` -***Program two*** uses __pthr*e*ad_cr*e*at*e*__ to creat a new __thr*e*ad__. __Thr*e*ads__ do not shear __memory spac*e*__. - +***Program two*** uses `pthread_create` to creat a new __Thread__. __Threads__ do not share __memory space__. ```C -//Program_two writen in pseudocode +#include +#include + +void *rutine(void *x) +{ + //2nd thread + printf("new thread value %d\n", *(int*)x); + *(int*)x += 1; + printf("new thread value %d\n", *(int*)x); + *(int*)x += 1; + printf("new thread value %d\n", *(int*)x); + *(int*)x += 1; + printf("new thread value %d\n", *(int*)x); + *(int*)x += 1; + return (NULL); +} + int main() { - int x; + int x; + pthread_t thread; - x = 25; - make_a_thread(); - thread - { - printf("new thread value %d\n", x++); - sleep(1); - printf("new thread value %d\n", x++); - sleep(1); - printf("new thread value %d\n", x++); - sleep(1); - printf("new thread value %d\n", x++); - sleep(1); - } - main thread - { - sleep(5); - printf("Main thread value %d\n", x); - } - return (0); + x = 25; + pthread_create(&thread, NULL, rutine, &x); + //main thread + pthread_join(thread, NULL); + printf("Main thread value %d\n", x); + return (0); } ``` `gcc Program_two.c; ./a.out #what can we expect the x value to be in thread?` +##### Can you answear these qestions? +1. What does it mean to share __memory space__ in sense of varibles? +2. Why is it useful to share __memory space__? -1. What do*e*s it m*e*an to sh*e*ar __m*e*mory spac*e*__ in s*e*ns*e* of varibl*e*s? -2. Why is it useful to sh*e*ar __m*e*mory spac*e*__? - -# One a practical not*e* ๐Ÿงถ +# One a practical note ๐Ÿงถ #### Allowed functions: @@ -107,35 +99,91 @@ int pthread_join(pthread_t thread, void **value_ptr); int printf(const char *restrict format, ...); ``` -### pthr*e*ad_t -1. What __data__ typ*e* is pthread_t? -2. Why us*e* pthr*e*ad_t not an __int__? +### `pthread_t` +`pthread_t` is a data type used to store Thread information. Maybe you have seen `pid_t` data type before? Then this is kind of simillar but in stead of process id which `pid_t` stores we store Thread info. + +##### Can you answear these qestions: + +1. What **data** type is pthread_t? +2. Why use pthread_t and not an __int__? + +### `pthread_create` + +##### Explination: +Just as it sounds `pthread_create` will make a new thread! Its super similar to `fork` but it makes a new proccess in stead of a thread. + +##### Example: +```C +#include + +void *rutine(void *ptr) +{ + (void)ptr; + return (NULL); +} + +int main() +{ + pthread_t thread; + + pthread_create(&thread, NULL, rutine, 0); + return (0); +} +``` + +##### Can you answear these qestions: -### pthr*e*ad_cr*e*at*e* -1. What __argum*e*nts__ do*e*s th*e* __pthr*e*ad_create__ tak*e*? -2. What is void \*(\*start_routin*e*)(void \*)? -3. What is *e*x*e*cut*e*d wh*e*n pthr*e*ad_cr*e*at*e* is call*e*d? -4. How would you pass __data__ to th*e* start_routin*e* function? -5. What is th*e* attr argum*e*nt? -6. Why us*e* pthr*e*ad_cr*e*at*e*? -7. Why not us*e* fork in st*e*ad of pthr*e*ad_cr*e*at*e*? +1. What __arguments__ does the `pthread_create` take? +2. What is `void *(*start_routine)(void *)?` +3. What is executed when `pthread_create` is called? +4. How would you pass __data__ to the `start_routine` function? +5. What is the `attr` argument? +6. Why use `pthread_create`? +7. Why not us*e* `fork` in st*e*ad of `pthread_create`? -### pthr*e*ad_join -1. What argum*e*nts do*e*s th*e* function tak*e*? -2. What is void \*\*valu*e*_ptr us*e*d for? -3. What hpp*e*ns if you do not call __pthr*e*ad_join__ aft*e*r __pthr*e*ad_cr*e*ate__ +### `pthread_join` + +Explination: +Just as it sounds `pthread_join` will join a thread to the main thread! +[threads are a little bit like jarn](https://www.youtube.com/watch?v=uA8X5zNOGw8&t=240s) + +##### Example: +```C +#include + +void *rutine(void *ptr) +{ + (void)ptr; + return (NULL); +} + +int main() +{ + pthread_t thread; + + pthread_create(&thread, NULL, rutine, 0); + pthread_join(thread, NULL); + return (0); +} +``` +##### Can you answear these qestions: + +1. What arguments does the function take? +2. What is `void **value_ptr` used for? +3. What hppens if you do not call `pthread_join` after `pthread_create` ## Goal ๐ŸŽฏ -Cr*e*at*e* a n*e*w thr*e*ad that outputs this m*e*ssag*e*! +Create a new Thread that outputs this message! ```sh $ ./ex01.out Hi From the thread. You can call me philosopher 1 ``` -#### L*e*arn how to cr*e*at*e* thr*e*ads in a loop. Cr*e*at*e* 20 thr*e*ads that will print th*e* following. +#### Learn how to create Threads in a loop. Create 20 Threads that will print the following. + +## Can you code this? ๐ŸŽฏ +#### Achieve this output -## Goal ๐ŸŽฏ -#### Achi*e*v*e* this output ```ASCII Hi From the thread. You can call me philosopher 1 Hi From the thread. You can call me philosopher 1 @@ -160,17 +208,17 @@ Hi From the thread. You can call me philosopher 1 Hi From the thread. You can call me philosopher 1 ``` -## Data rac*e*s/rac*e* conditions +## Data Races/race conditions -[Whatch a vid*e*o about data rac*e*s till 9:10](https://www.youtube.com/watch?v=FY9livorrJI) +[Whatch a video about data Races till 9:10](https://www.youtube.com/watch?v=FY9livorrJI) -1. What ar*e* __data rac*e*s?__ -2. What is a __critical s*e*ction?__ -3. If two or mor*e* __thr*e*ads__ ar*e* r*e*ading th*e* valu*e* at th*e* sam*e* tim*e* is that a __data rac*e*__? -4. Can th*e* compil*e*r h*e*lp spot __data rac*e*s__? -5. Why ar*e* __data rac*e*s__ bad? +##### Can you answear these qestions: -##### Do you s*ee* a __data rac*e*__ in this cod*e*? +1. What are __data Races?__ +2. What is a __critical section?__ +3. If two or more __Threads__ are reading the value at the same time is that a __data race__? +4. Can the compiler help spot __data Races__? +5. Why are __data Races__ bad? ```C // example code @@ -207,13 +255,15 @@ int main() return (0); } ``` +##### Can you answer thes qestions: +1. Do you see a *data race* in this code? +2. Where there a **critical section**? -##### Wh*e*r*e* is th*e*r*e* a __critical s*e*ction__? +## Let's talk Mutexes -## L*e*t's talk mut*e*x*e*s -Th*e* solution to __data rac*e*s__ can b*e* __mut*e*x*e*s__. Wh*e*n a __mut*e*x__ is us*e*d it *e*nsur*e*s that only on*e* __thr*e*ad__ can acc*e*ss a pi*e*c*e* of cod*e* at a tim*e*. Mutual *e*xclusion. +The solution to __data Races__ can be __Mutexes__. When a __mutex__ is used it ensures that only one __Thread__ can access a piece of code at a time. Mutual exclusion. -#### Allow*e*d functions +#### Allowed functions ```C #include @@ -226,53 +276,120 @@ int pthread_mutex_init(pthread_mutex_t mutex, const pthread_mutexattr_t attr); int pthread_mutex_destroy(pthread_mutex_t mutex); ``` -For r*e*f*e*r*e*nc*e* This is how the __pthr*e*ad_mut*e*x_t data__ typ*e* looks lik*e*. +For reference This is how the `pthread_mutex_t` __data__ type looks like. ```C struct _opaque_pthread_mutex_t { long __sig; - char __opaque[__PTHREAD_MUTEX_SIZE__]; + char __opaque[__PTHREAD_mutex_SIZE__]; }; ``` -1. What is th*e* __pthr*e*ad_mut*e*x_t data__ typ*e*? +1. What is the `pthread_mutex_t` __data__ type? + +### `pthread_mutex_init` +##### Explination: +Just as the name suggest `pthread_mutex_init` will initialize a mutex. +##### Example: +```C +#include -### pthr*e*ad_mut*e*x_init -1. What do*e*s this function do? -2. Why do w*e* n*ee*d to init a mut*e*x? +int main() +{ + pthread_mutex_t mutex; -### pthr*e*ad_mut*e*x_d*e*stroy -1. What do*e*s this function do? -2. Do you hav*e* to fr*ee* th*e* mut*e*x? -3. Do you n*ee*d to d*e*stroy init*e*d mut*e*x*e*s? + pthread_mutex_init(&mutex, NULL); + return (0); +} +``` +##### Can you answer these qestions? +1. What does this function do? +2. Why do we need to init a mutex? + +### `pthread_mutex_destroy` +Explination: +Just as the name suggest `pthread_mutex_destroy` will destroy a mutex. +##### Example: + +```C +#include + +int main() +{ + pthread_mutex_t mutex; + + pthread_mutex_destroy(&mutex); + return (0); +} +``` +##### Can you answer these qestions? + +1. What does this function do? +2. Do you have to `free` the mutex? +3. Do you need to destroy inited mutexes? 4. Can a locked mutex be destroyed? -### pthr*e*ad_mut*e*x_lock -1. What do*e*s this function do? -2. Can you lock a mut*e*x 2 tim*e*s? +### `pthread_mutex_lock` +##### Explination: +Just as the name suggest `pthread_mutex_lock` will do the magic of fixing the data race. +##### Example: +```C +#include -### pthr*e*ad_mut*e*x_unlock -1. What do*e*s this function do? +int main() +{ + pthread_mutex_t mutex; -## Goal ๐ŸŽฏ + pthread_mutex_lock(&mutex); + return (0); +} +``` +##### Can you answer these qestions: -Mak*e* a program that inits, locks, unlock and d*e*stroys a mut*e*x! +1. What does this function do? +2. Can you lock a mutex 2 times? +3. Why do we need to lock Mutexes? -## Goal ๐ŸŽฏ +### `pthread_mutex_unlock` +##### Explination: +Just as the name suggest `pthread_mutex_unlock`, will unlock a thread making the lock unlocked means that other threads will be able to lock it so that other threads will be able to prevent data races! +##### Example: +```C +#include + +int main() +{ + pthread_mutex_t mutex; + + pthread_mutex_unlock(&mutex); + return (0); +} +``` + +##### Can you answer these qestions: + +1. What does this function do? +2. Why do we need to unlock Mutexes? -Pr*e*v*e*nt th*e* data rac*e* in th*e* *e*xampl*e* cod*e*. +## Can you code this? ๐ŸŽฏ + +Make a program that inits, locks, unlock and destroys a Mutex! + +## Can you code this? ๐ŸŽฏ + +Prevent the data race in the example code. ```C // example code #include #include -void rutine(void ptr) +void *rutine(void *ptr) { while (1) { - if ((int )ptr < 1000) + if (*(int *)ptr < 1000) break ; - (int )ptr += 1; + *(int *)ptr += 1; } printf("Done\n"); return (NULL); @@ -296,19 +413,23 @@ int main() } ``` -## D*e*adlocks +## Deadlocks +##### Explination: Deadlock is a state in a programm where all the available mutexes have been locked, thou more and more threads are trying to lock more mutexes in result the programm hangs. -1. What is a __d*e*adlock__? -2. Wh*e*n do*e*s a __d*e*adlock__ occur? -## Goal ๐ŸŽฏ +##### Can you answer these qestions? + +1. What is a **Deadlock**? +2. When does a **Deadlock** occur? -Produc*e* a program that has a __d*e*adlock__. +## Can you code this? ๐ŸŽฏ -## Why not us*e* thr*e*ads? +Produce a program that has a Deadlock. -It s*e*ams that having mor*e* thr*e*ads would sp*ee*d things up, but it's not always th*e* cas*e*. -B*e*llow, 2 programs add up to INT_MAX / 100. On*e* us*e*s 20 __thr*e*ads__ and on*e* us*e*s just on*e*. Which will b*e* fast*e*r? +## Why not use threads? + +It seems that having more threads would speed things up, but it's not always the case. +Bellow, 2 programs add up to INT_MAX / 100. One uses 20 **threads** and one uses just one. Which will be faster? ```C #include @@ -318,25 +439,25 @@ B*e*llow, 2 programs add up to INT_MAX / 100. On*e* us*e*s 20 __thr*e*ads__ and typedef struct s_list { - int num; + int *num; pthread_mutex_t lock; } t_list; #define MAX_PHILO 20 -void rutine(void ptr) +void *rutine(void *ptr) { - t_list philo = ptr; + t_list *philo = ptr; while (1) { pthread_mutex_lock(&philo->lock); - if (philo->num > INT_MAX / 100) + if (*philo->num > INT_MAX / 100) { pthread_mutex_unlock(&philo->lock); return (NULL); } - philo->num += 1; + *philo->num += 1; pthread_mutex_unlock(&philo->lock); } return (NULL); @@ -346,9 +467,9 @@ int main() { pthread_t thread[MAX_PHILO]; t_list philosopher[MAX_PHILO]; - int x = malloc(sizeof(int)); + int *x = malloc(sizeof(int)); - x = 0; + *x = 0; for (int i = 0; i < 20; i++) { pthread_mutex_init(&philosopher[i].lock, NULL); @@ -362,7 +483,7 @@ int main() pthread_join(thread[i], NULL); pthread_mutex_destroy(&philosopher[i].lock); } - printf("%d\n", philosopher[0].num); + printf("%d\n", *philosopher[0].num); free(philosopher[0].num); return (0); } @@ -386,10 +507,10 @@ int main() } ``` -## Goal ๐ŸŽฏ -compil*e* both programms and us*e* `time ./a.out` to s*ee* which is fast*e*r +## Can you code this? ๐ŸŽฏ +compile both programms and use `time ./a.out` to see which is faster -#### Allow*e*d functions +#### Allowed functions ```C #include @@ -404,9 +525,9 @@ int pthread_join(pthread_t thread, void value_ptr); int printf(const char restrict format, ...); ``` -## Goal ๐ŸŽฏ -cr*e*at 20 thr*e*ads that will print th*e* following -th*e* ord*e*r do*e*s not matt*e*r +## Can you code this? ๐ŸŽฏ +creat 20 threads that will print the following +the order does not matter ```ASCII Hi From the thread. You can call me philosopher 1 @@ -434,20 +555,14 @@ Hi From the thread. You can call me philosopher 21 # Bonus -Mak*e* a program that will us*e* 3 cr*e*at*e*d thr*e*ads to add up an int to 42. Thr*e*ads can incr*e*m*e*nt th*e* int *e*v*e*ry .5s*e*c -onc*e* th*e* valu*e* is 42 th*e* program has to print "Got it!\n" and *e*xit. +Make a program that will use 3 created threads to add up an int to 42. Threads can increment the int every .5 sec +once the value is 42 the program has to print "Got it!\n" and exit. catch: -Th*e* thr*e*ads do not know wh*e*n th*e* valu*e* is 42 - -What is a monitoring thr*e*ad? - -A monitoring thr*e*ad is a conc*e*pt us*e*d in th*e* philosoph*e*r's proj*e*ct. a monitoring thr*e*ad will k*ee*p track of th*e* int variabl*e*. If th*e* valu*e* is 42 l*e*t th*e* thr*e*ads know to finish and *e*xit. +The threads do not know when the value is 42 +What is a monitoring thread? -# Aditional r*e*sourc*e*s: -##### [*Th*e*ory on what ar*e* thr*e*ads*](https://csc-knu.github.io/sys-prog/books/Andrew%20S.%20Tanenbaum%20-%20Modern%20Operating%20Systems.pdf#%5B%7B%22num%22%3A3419%2C%22gen%22%3A0%7D%2C%7B%22nam*e*%22%3A%22XYZ%22%7D%2C16%2C753%2C1%5D) -##### [*Vid*e*os with practical *e*xampl*e*s*](https://www.youtube.com/watch?v=d9s_d28yJq0&list=PLfqABt5AS4FmuQf70psXrsMLEDQXNkLq2) -Look in to what a sch*e*dul*e*r is! +A monitoring thread is a concept used in the philosopher's project. a monitoring thread will keep track of the int variable. If the value is 42 let the threads know to finish and exit. From fcc6757476dfb9a7a9d4633c93403ffb74b7e078 Mon Sep 17 00:00:00 2001 From: krusts31 Date: Wed, 8 Jun 2022 15:43:03 +0200 Subject: [PATCH 6/6] renamed philosopher spark session names --- ...philosophers - mod.md => SparkSession - philosophers - mod.md} | 0 ...arkSession -philosophers.md => SparkSession - philosophers.md} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename spark-sessions/philosophers/{SparkSession -philosophers - mod.md => SparkSession - philosophers - mod.md} (100%) rename spark-sessions/philosophers/{SparkSession -philosophers.md => SparkSession - philosophers.md} (100%) diff --git a/spark-sessions/philosophers/SparkSession -philosophers - mod.md b/spark-sessions/philosophers/SparkSession - philosophers - mod.md similarity index 100% rename from spark-sessions/philosophers/SparkSession -philosophers - mod.md rename to spark-sessions/philosophers/SparkSession - philosophers - mod.md diff --git a/spark-sessions/philosophers/SparkSession -philosophers.md b/spark-sessions/philosophers/SparkSession - philosophers.md similarity index 100% rename from spark-sessions/philosophers/SparkSession -philosophers.md rename to spark-sessions/philosophers/SparkSession - philosophers.md