owned this note
owned this note
Published
Linked with GitHub
# Lektion 4
Denna lektion introducerar lab 3. Vi kommer leka lite med: pthreads, mutex, helgrind och lite annat.
## POSIX trådar (pthreads)
![meme](https://i.imgur.com/byaQL7Q.png)
0. Läs dokumentationen för pthreads. Du kommer behöva länka pthread biblioteket vid kompilering, dvs lägga till `-lpthread` flaggan till `gcc`
1. Skapa ett program där en tråd skriver ut "Hello World!". Använd `pthread_create()`
2. Utöka programmet så att du skickar ordet "World" som argument till din tråd.
3. Skapa 10 trådar som kör funktionen nedan:
```c
void *thread_func(void *arg) {
char* buf = "Multithreading är kul!\n";
for(int i = 0; i < strlen(buf); i++){
write(STDOUT_FILENO, &buf[i], 1);
usleep(1);
}
return NULL;
}
```
3. Vad får du för output? Varför skrivs strängen ut så? Hur kan vi fixa problemet?
4. Läs om mutex och försök lösa problemet.
5. Koden nedan har nästan samma problem, kan du fixa den? Använd`valgrind` med `helgrind` metoden för att debugga.
```c
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int value = 0;
void write_value(int v){
usleep(250000);
value = v;
}
int read_value(){
usleep(250000);
return value;
}
void* update_value(void *x){
int v = read_value();
write_value(v + *(int *)x);
return NULL;
}
int main(){
printf("Before: %d\n", read_value());
int v1 = 100;
int v2 = 800;
pthread_t ptid1;
pthread_t ptid2;
pthread_create(&ptid1, NULL, update_value, (void *) &v1);
pthread_create(&ptid2, NULL, update_value, (void *) &v2);
pthread_join(ptid1, NULL);
pthread_join(ptid2, NULL);
printf("After: %d\n", read_value());
}
```
6. Använd samma hello world programmet från tidigare, med 5 tråder, och låt den sista tråden skriva ut först. Använd condition variablar. Du kommer behöva skicka arguments till tråden.
7. Läs koden nedan och försök att gissa vad den gör. Vad händer? Kan du fixa problemet?
```c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <string.h>
struct resource{
pthread_mutex_t lock1;
pthread_mutex_t lock2;
};
typedef struct resource Resource;
void *thread_func1(void *arg) {
Resource *res = (Resource *)arg;
int counter = 0;
printf("Thread %d started\n", 1);
while (1) {
pthread_mutex_lock(&res->lock1);
pthread_mutex_lock(&res->lock2);
printf("Thread %d counter: %d\n", 1, counter);
counter++;
pthread_mutex_unlock(&res->lock1);
pthread_mutex_unlock(&res->lock2);
}
return NULL;
}
void *thread_func2(void *arg) {
Resource *res = (Resource *)arg;
int counter = 0;
printf("Thread %d started\n", 2);
while (1) {
pthread_mutex_lock(&res->lock2);
pthread_mutex_lock(&res->lock1);
printf("Thread %d counter: %d\n", 2, counter);
counter++;
pthread_mutex_unlock(&res->lock2);
pthread_mutex_unlock(&res->lock1);
}
return NULL;
}
Resource *resource_create(){
Resource *res = malloc(sizeof(Resource));
pthread_mutex_init(&res->lock1, NULL);
pthread_mutex_init(&res->lock2, NULL);
return res;
}
int main(void) {
pthread_t thread1[1];
pthread_t thread2[1];
Resource *res1 = resource_create();
pthread_create(thread1, NULL, thread_func1, res1);
pthread_create(thread2, NULL, thread_func2, res1);
pthread_join(thread1[0], NULL);
pthread_join(thread2[0], NULL);
return 0;
}
```
## Directories
0. Använd `opendir()` för att skriv ut namnet på alla filer i hemma katalog.
1. Utöka programmet så att det skriver ut bara .c filer.
2. Implementera en DFS algoritm för att leta efter en fil givet en start dir.
3. Utöka programmet för att skriva storleken på filen. Använd `lstat()`