# threads

***

**1. Creating and Joining Threads**

```c
#include <pthread.h>

void* thread_func(void* arg) {
    printf("Hello from thread!\n");
    return NULL;
}

int main() {
    pthread_t thread;
    pthread_create(&thread, NULL, thread_func, NULL);
    pthread_join(thread, NULL);
    return 0;
}
```

**2. Concurrent Task Execution**

```c
#include <pthread.h>
#include <stdio.h>

void* thread_func1(void* arg) {
    for (int i = 0; i < 10000; i++) {
        printf("Thread 1: %d\n", i);
    }
    return NULL;
}

void* thread_func2(void* arg) {
    for (int i = 0; i < 10000; i++) {
        printf("Thread 2: %d\n", i);
    }
    return NULL;
}

int main() {
    pthread_t thread1, thread2;
    pthread_create(&thread1, NULL, thread_func1, NULL);
    pthread_create(&thread2, NULL, thread_func2, NULL);
    pthread_join(thread1, NULL);
    pthread_join(thread2, NULL);
    return 0;
}
```

**3. Shared Data Access: Mutex**

```c
#include <pthread.h>
#include <stdio.h>

pthread_mutex_t mutex;

void* thread_func(void* arg) {
    pthread_mutex_lock(&mutex);
    printf("Thread %ld entered critical section\n", pthread_self());
    // Perform critical operations
    pthread_mutex_unlock(&mutex);
    return NULL;
}

int main() {
    pthread_t threads[5];
    pthread_mutex_init(&mutex, NULL);
    for (int i = 0; i < 5; i++) {
        pthread_create(&threads[i], NULL, thread_func, NULL);
    }
    for (int i = 0; i < 5; i++) {
        pthread_join(threads[i], NULL);
    }
    pthread_mutex_destroy(&mutex);
    return 0;
}
```

**4. Shared Data Access: Semaphore**

```c
#include <pthread.h>
#include <semaphore.h>

sem_t semaphore;
int shared_data;

void* thread_func(void* arg) {
    sem_wait(&semaphore);
    // Access and modify shared_data
    sem_post(&semaphore);
    return NULL;
}

int main() {
    pthread_t threads[5];
    sem_init(&semaphore, 0, 1);  // Initial value of semaphore is 1
    for (int i = 0; i < 5; i++) {
        pthread_create(&threads[i], NULL, thread_func, NULL);
    }
    for (int i = 0; i < 5; i++) {
        pthread_join(threads[i], NULL);
    }
    sem_destroy(&semaphore);
    return 0;
}
```

**5. Condition Variables**

```c
#include <pthread.h>
#include <stdio.h>

pthread_cond_t cond;
pthread_mutex_t mutex;
int shared_data;

void* thread_func1(void* arg) {
    while (1) {
        pthread_mutex_lock(&mutex);
        while (shared_data == 0) {
            pthread_cond_wait(&cond, &mutex);
        }
        // Access and process shared_data
        pthread_mutex_unlock(&mutex);
    }
}

void* thread_func2(void* arg) {
    while (1) {
        pthread_mutex_lock(&mutex);
        shared_data = 1;
        printf("Notifying thread 1\n");
        pthread_cond_signal(&cond);
        pthread_mutex_unlock(&mutex);
    }
}

int main() {
    pthread_t thread1, thread2;
    pthread_cond_init(&cond, NULL);
    pthread_mutex_init(&mutex, NULL);
    pthread_create(&thread1, NULL, thread_func1, NULL);
    pthread_create(&thread2, NULL, thread_func2, NULL);
    pthread_join(thread1, NULL);
    pthread_join(thread2, NULL);
    return 0;
}
```

**6. Producer-Consumer**

```c
#include <pthread.h>
#include <semaphore.h>

sem_t full, empty;
int buffer[10];
int in, out;

void* producer(void* arg) {
    while (1) {
        sem_wait(&empty);
        buffer[in] = 1;
        in = (in + 1) % 10;
        sem_post(&full);
    }
}

void* consumer(void* arg) {
    while (1) {
        sem_wait(&full);
        int item = buffer[out];
        out = (out + 1) % 10;
        sem_post(&empty);
        // Process item
    }
}

int main() {
    pthread_t prod_threads[5], cons_threads[5];
    sem_init(&full, 0, 0);
    sem_init(&empty, 0, 10);
    for (int i = 0; i < 5; i++) {
        pthread_create(&prod_threads[i], NULL, producer, NULL);
        pthread_create(&cons_threads[i], NULL, consumer, NULL);
    }
    for (int i = 0; i < 5; i++) {
        pthread_join(prod_threads[i], NULL);
        pthread_join(cons_threads[i], NULL);
    }
    return 0;
}
```

**7. Dining Philosophers**

```c
#include <pthread.h>
#include <semaphore.h>

pthread_mutex_t chopsticks[5];
sem_t semaphore;

void* philosopher(void* arg) {
    while (1) {
        int id = *(int*)arg;
        printf("Philosopher %d is thinking\n", id);
        sem_wait(&semaphore);
        pthread_mutex_lock(&chopsticks[id]);
        pthread_mutex_lock(&chopsticks[(id + 1) % 5]);
        sem_post(&semaphore);
        printf("Philosopher %d is eating\n", id);
        pthread_mutex_unlock(&chopsticks[(id + 1) % 5]);
        pthread_mutex_unlock(&chopsticks[id]);
    }
}

int main() {
    pthread_t philosophers[5];
    int ids[5] = {0, 1, 2, 3, 4};
    for (int i = 0; i < 5; i++) {
        pthread_mutex_init(&chopsticks[i], NULL);
    }
    sem_init(&semaphore, 0, 4);  // Allow 4 philosophers to eat at a time
    for (int i = 0; i < 5; i++) {
        pthread_create(&philosophers[i], NULL, philosopher, &ids[i]);
    }
    for (int i = 0; i < 5; i++) {
        pthread_join(philosophers[i], NULL);
    }
    return 0;
}
```

**8. Read-Write Lock**

```c
#include <pthread.h>
#include <stdio.h>

pthread_rwlock_t rwlock;

void* write_thread_func(void* arg) {
    pthread_rwlock_wrlock(&rwlock);
    printf("Write thread acquired write lock\n");
    // Perform write operations
    pthread_rwlock_unlock(&rwlock);
    printf("Write thread released write lock\n");
    return NULL;
}

void* read_thread_func(void* arg) {
    pthread_rwlock_rdlock(&rwlock);
    printf("Read thread acquired read lock\n");
    // Perform read operations
    pthread_rwlock_unlock(&rwlock);
    printf("Read thread released read lock\n");
    return NULL;
}

int main() {
    pthread_rwlock_init(&rwlock, NULL);
    pthread_t write_threads[5], read_threads[5];
    for (int i = 0; i < 5; i++) {
        pthread_create(&write_threads[i], NULL, write_thread_func, NULL);
    }
    for (int i = 0; i < 5; i++) {
        pthread_create(&read_threads[i], NULL, read_thread_func, NULL);
    }
    for (int i = 0; i < 5; i++) {
        pthread_join(write_threads[i], NULL);
        pthread_join(read_threads[i], NULL);
    }
    pthread_rwlock_destroy(&rwlock);
    return 0;
}
```

**9. Thread Priority**

```c
#include <pthread.h>
#include <stdio.h>

void* thread_func(void* arg) {
    for (int i = 0; i < 10; i++) {
        printf("Thread %ld has priority %d\n", pthread_self(), sched_get_priority(0));
    }
    return NULL;
}

int main() {
    pthread_t threads[5];
    struct sched_param param;
    for (int i = 0; i < 5; i++) {
        param.sched_priority = i + 1;
        pthread_create(&threads[i], NULL, thread_func, NULL);
        pthread_setschedparam(threads[i], SCHED_FIFO, &param);
    }
    for (int i = 0; i < 5; i++) {
        pthread_join(threads[i], NULL);
    }
    return 0;
}
```

**10. Thread-Specific Data**

```c
#include <pthread.h>
#include <stdio.h>

pthread_key_t key;

void* thread_func(void* arg) {
    int* data = pthread_getspecific(key);
    printf("Thread %ld has thread-specific data %d\n", pthread_self(), *data);
    return NULL;
}

int main() {
    pthread_key_create(&key, NULL);
    pthread_t threads[5];
    for (int i = 0; i < 5; i++) {
        int* data = malloc(sizeof(int));
        *data = i;
        pthread_setspecific(key, data);
        pthread_create(&threads[i], NULL, thread_func, NULL);
    }
    for (int i = 0; i < 5; i++) {
        pthread_join(threads[i], NULL);
    }
    pthread_key_delete(key);
    return 0;
}
```

**11. Barrier Synchronization**

```c
#include <pthread.h>
#include <stdio.h>

pthread_barrier_t barrier;

void* thread_func(void* arg) {
    printf("Thread %ld waiting at barrier\n", pthread_self());
    pthread_barrier_wait(&barrier);
    printf("Thread %ld passed barrier\n", pthread_self());
    return NULL;
}

int main() {
    pthread_t threads[5];
    pthread_barrier_init(&barrier, NULL, 5);
    for (int i = 0; i < 5; i++) {
        pthread_create(&threads[i], NULL, thread_func, NULL);
    }
    for (int i = 0; i < 5; i++) {
        pthread_join(threads[i], NULL);
    }
    pthread_barrier_destroy(&barrier);
    return 0;
}
```

**12. Once Initialization**

```c
#include <pthread.h>
#include <stdio.h>

pthread_once_t once_control;
int global_data;

void init_func() {
    global_data = 42;
    printf("Global data initialized to %d\n", global_data);
}

void* thread_func(void* arg) {
    pthread_once(&once_control, init_func);
    printf("Thread %ld has access to global data %d\n", pthread_self(), global_data);
    return NULL;
}

int main() {
    pthread_t threads[5];
    for (int i = 0; i < 5; i++) {
        pthread_create(&threads[i], NULL, thread_func, NULL);
    }
    for (int i = 0; i < 5; i++) {
        pthread_join(threads[i], NULL);
    }
    return 0;
}
```

**13. Thread Local Storage**
