summaryrefslogtreecommitdiff
path: root/02-26.md
diff options
context:
space:
mode:
Diffstat (limited to '02-26.md')
-rw-r--r--02-26.md172
1 files changed, 172 insertions, 0 deletions
diff --git a/02-26.md b/02-26.md
new file mode 100644
index 0000000..ef1c0a5
--- /dev/null
+++ b/02-26.md
@@ -0,0 +1,172 @@
+[\<- Notes 02/21](02-21.md)
+
+---
+
+# Threading Continued
+
+## Locking
+
+- Sharing Variables
+ - Requires mutual exclusion
+ - Lock/unlock to avoid a race condition
+- Have one lock for each independent critical region
+
+- Bad Example (no synchronization):
+
+```
+int count = 0;
+
+void *update(){ //returns a pointer with no given data type
+ int i;
+
+ for(i = 0; i < 1000; i++){
+ count++;
+ }
+}
+```
+
+- Good Example (using lock):
+
+```
+int count = 0;
+
+void *update(){ //returns a pointer with no given data type
+ int i;
+
+ for(i = 0; i < 1000; i++){
+ //lock
+ count++;
+ //unlock
+ }
+}
+```
+
+- More real world example:
+
+```
+int balance = 100; //$100
+
+//process 1: withdraw $20
+ //read balance (i.e $100)
+ //write new balance (i.e $80)
+
+//process 2: withdraw $30
+ //read balance (i.e $80)
+ //write new balance (i.e $50)
+```
+
+- In the above example, you need to use lock to avoid one process reading the balance before the other process finishes writing
+
+## pthread library
+
+- We will use the Linux pthread library
+ - Main information
+ - `man pthread`
+ - There are man pages for specific functions
+ - Include ".h" file as shown in the man page: `#include <pthread.h>`
+ - Compile using `-lpthread`
+
+- Operations:
+
+```
+#include <pthread.h>
+
+pthread_t thread;
+
+int pthread_create(
+ pthread_t *restrict thread, //thread id
+ const pthread_attr_t *restrict attr, //attributes
+ void *(*start_routine)(void *), //function
+ void *restrict arg); //argument
+```
+
+- More operations:
+ - `void pthread_exit(void *value_ptr);`
+ - `int pthread_join(pthread_t thread, void **value_ptr);`
+
+- Example using pthreads
+ - Alternating threads
+ - Creates 3 threads
+ - Let the system execute them in a round-robin fashion
+ - Wait for them to finish at main
+
+```
+#include <stdio.h>
+#include <pthread.h> //this is the library that allows for threading
+
+void *loopThread(void *arg);
+
+int main(){
+ int i;
+ pthread_t thr[3];
+
+ for(i = 0; i < 3; i++){
+ pthread_create(&thr[i], NULL, loopThread, (void *)i);
+ }
+ for(i = 0; i < 3; i++){
+ pthread_join(thr[i], NULL);
+ }
+}
+
+void *loopThread(void *arg){
+ int i, j;
+ int threadNo = (int)arg; //cast the void pointer
+
+ for(i = 0; i < 20; i++){
+ printf("Thread %d\n", threadNo);
+ sleep(1);
+ }
+}
+```
+
+- Functions:
+
+```
+pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER
+
+//INIT
+int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);
+
+//LOCK
+int pthread_mutex_lock(pthread_mutex_t *mutex);
+
+//UNLOCK
+int pthread_mutex_unlock(pthread_mutex_t *mutex);
+```
+
+- Example using mutex lock:
+
+```
+//Using mutex lock
+//pthread_mutex_init called in main
+
+int count = 0;
+pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
+
+void *update(){
+ int i;
+
+ while(i = 0; i < 1000; i++){
+ pthread_mutex_lock(&mutex);
+ count++;
+ pthread_mutex_unlock(&mutex);
+ }
+}
+```
+
+- Danger!
+ - When one or more threads are waiting for one another and no thread can proceed
+- Example:
+ - One thread is waiting for itself
+ - Two threads are waiting for each other
+ - Several threads are waiting for one another in a cycle
+
+## Performance Considerations
+
+- Thread creation is expensive
+- Each thread has its own stack
+- Lock contention requires skills to keep many threads as possible running
+
+---
+
+[-> Notes 03/04](03-04.md)