Merge branch 'feature/downloader'
This commit is contained in:
@@ -47,6 +47,20 @@ This is an organized list of all exercises completed so far, including a brief d
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## 📥 downloader
|
||||||
|
|
||||||
|
**Description**: A multi-threaded simulated file downloader implemented in C using POSIX threads (pthreads).
|
||||||
|
|
||||||
|
- 📄 [README](downloader/README.md)
|
||||||
|
- 📂 Directory: `downloader/`
|
||||||
|
- ✅ Features:
|
||||||
|
- Each thread simulates downloading a file by printing periodic progress updates
|
||||||
|
- Synchronization using `pthread` APIs
|
||||||
|
- Demonstrates creation, execution, and joining of threads
|
||||||
|
- Makefile included with standard targets
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## 🔧 Tooling & Automation
|
## 🔧 Tooling & Automation
|
||||||
|
|
||||||
**Shared tools and scripts used across projects**:
|
**Shared tools and scripts used across projects**:
|
||||||
@@ -56,4 +70,4 @@ This is an organized list of all exercises completed so far, including a brief d
|
|||||||
- Shell script for automated tests: `run_tests.sh`
|
- Shell script for automated tests: `run_tests.sh`
|
||||||
- Valgrind memory check reports generated automatically
|
- Valgrind memory check reports generated automatically
|
||||||
|
|
||||||
*Last updated: 2025-07-09*
|
*Last updated: 2025-07-30*
|
||||||
|
|||||||
27
exercises/downloader/Makefile
Normal file
27
exercises/downloader/Makefile
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
# Makefile for Multi-threaded File Downloader
|
||||||
|
|
||||||
|
CC := gcc
|
||||||
|
CFLAGS := -Wall -Wextra -pedantic -std=c11 -pthread -g
|
||||||
|
TARGET := downloader
|
||||||
|
SRC := main.c
|
||||||
|
OBJS := $(SRC:.c=.o)
|
||||||
|
|
||||||
|
.PHONY: all clean test valgrind
|
||||||
|
|
||||||
|
all: $(TARGET)
|
||||||
|
|
||||||
|
$(TARGET): $(OBJS)
|
||||||
|
$(CC) $(CFLAGS) -o $@ $^
|
||||||
|
|
||||||
|
%.o: %.c
|
||||||
|
$(CC) $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
test: $(TARGET)
|
||||||
|
./downloader test1.txt test2.txt test3.txt
|
||||||
|
|
||||||
|
valgrind: $(TARGET)
|
||||||
|
valgrind --leak-check=full ./downloader test1.txt test2.txt
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f $(TARGET) $(OBJS)
|
||||||
|
|
||||||
89
exercises/downloader/README.md
Normal file
89
exercises/downloader/README.md
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
# 🧵 Multi-threaded File Downloader (Simulated)
|
||||||
|
|
||||||
|
This project simulates a multi-threaded file downloader in C using POSIX threads (`pthreads`). The goal is to practice creating and managing threads, synchronizing access to shared resources, and simulating parallel file downloads.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📋 Description
|
||||||
|
|
||||||
|
Each file provided via command-line arguments is "downloaded" by a separate thread. The download is simulated by printing log messages and sleeping for a random duration. All threads run concurrently and the main thread waits for them to complete.
|
||||||
|
|
||||||
|
This project is inspired by Chapter 7 ("Threads") of *Linux System Programming* by Robert Love.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚀 Usage
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ ./downloader file1.txt file2.txt file3.txt
|
||||||
|
````
|
||||||
|
|
||||||
|
Each file will be "downloaded" in parallel by a separate thread. The program prints informative messages about the start and completion of each download.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🛠️ Features
|
||||||
|
|
||||||
|
* One thread per file
|
||||||
|
* Simulated download using `sleep()`
|
||||||
|
* Optional logging to file (future enhancement)
|
||||||
|
* Thread-safe output via `pthread_mutex_t`
|
||||||
|
* Clean thread termination via `pthread_join`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🧪 Example Output
|
||||||
|
|
||||||
|
```
|
||||||
|
[Thread 0x7fdc9a10]: Starting download of file1.txt
|
||||||
|
[Thread 0x7fdc9210]: Starting download of file2.txt
|
||||||
|
[Thread 0x7fdc9210]: Finished download of file2.txt
|
||||||
|
[Thread 0x7fdc9a10]: Finished download of file1.txt
|
||||||
|
All downloads complete.
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📂 Project Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
multidownload/
|
||||||
|
├── main.c # Main program
|
||||||
|
├── Makefile # Build script
|
||||||
|
└── README.md # Project documentation
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🧵 Concepts Practiced
|
||||||
|
|
||||||
|
* Thread creation with `pthread_create`
|
||||||
|
* Thread joining with `pthread_join`
|
||||||
|
* Synchronization with `pthread_mutex_t`
|
||||||
|
* Struct-based thread argument passing
|
||||||
|
* Output race condition prevention
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🏗️ Build
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ make
|
||||||
|
```
|
||||||
|
|
||||||
|
To clean the build:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ make clean
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📖 References
|
||||||
|
|
||||||
|
* *Linux System Programming* by Robert Love — Chapter 7: Threads
|
||||||
|
* POSIX Threads (man 7 pthread)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*Last updated: 2025-07-28*
|
||||||
41
exercises/downloader/main.c
Normal file
41
exercises/downloader/main.c
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
#define _GNU_SOURCE
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/syscall.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
static void *download(void *);
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
if (argc < 2) {
|
||||||
|
fprintf(stderr, "Usage: %s file1 file2...", argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int nfile = argc - 1;
|
||||||
|
pthread_t workers[nfile];
|
||||||
|
for (int i = 0; i < nfile; i++) {
|
||||||
|
pthread_create(&workers[i], NULL, download, argv[i + 1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < nfile; i++) {
|
||||||
|
pthread_join(workers[i], NULL);
|
||||||
|
}
|
||||||
|
printf("All downloads complete.\n");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void *download(void *arg)
|
||||||
|
{
|
||||||
|
char *uri = (char *)arg;
|
||||||
|
int tid = syscall(SYS_gettid);
|
||||||
|
printf("[Thread %x] Starting download of %s\n", tid, uri);
|
||||||
|
sleep(rand() % 3 + 1);
|
||||||
|
printf("[Thread %x] Finished download of %s\n", tid, uri);
|
||||||
|
pthread_exit(0);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user