Follow and star our public account for direct access to exciting content

Content
1. Basic Concepts of Multithreading
1. What is a Thread?
A thread is the smallest unit of execution in a program, representing an independent execution path within a process. A process can contain multiple threads that share the process’s memory space (such as global variables and heap memory), but each thread has its own stack space (used for storing local variables and function call information).
2. Difference Between Threads and Processes
| Characteristic | Process | Thread |
|---|---|---|
| Memory Space | Independent memory space | Shares the process’s memory space |
| Resource Overhead | High cost for creation and destruction | Low cost for creation and destruction |
| Communication Method | Requires inter-process communication (IPC) | Directly shares memory, communication is more efficient |
| Context Switching | High switching cost | Low switching cost |
| Stability | A process crash does not affect other processes | A thread crash may cause the entire process to crash |
3. Why Use Multithreading?
- Improves program responsiveness: For example, in GUI programs, the main thread handles the interface while child threads handle time-consuming tasks.
- Fully utilizes multi-core CPUs: Multithreading can execute in parallel, enhancing computational efficiency.
- Simplifies the development of complex tasks: Break down tasks into multiple threads for clearer logic.
2. Implementing Multithreading in C (POSIX Thread Library)
1. Introduction to POSIX Thread Library
The C language does not directly support multithreading, but multithreading programming can be achieved through the POSIX Thread Library (pthread). This library is cross-platform, primarily used in Linux/Unix systems, while Windows requires the Win32 API (this article uses pthread as an example).
2. Basic Functions
| Function | Purpose |
|---|---|
<span>pthread_create()</span> |
Create a thread |
<span>pthread_join()</span> |
Wait for a thread to finish |
<span>pthread_exit()</span> |
Terminate the current thread |
<span>pthread_detach()</span> |
Set the thread to detached state (no need to wait) |
<span>pthread_mutex_lock()</span> |
Lock (protect shared resources) |
<span>pthread_mutex_unlock()</span> |
Unlock |
<span>pthread_cond_wait()</span> |
Condition variable wait |
<span>pthread_cond_signal()</span> |
Wake up waiting threads |
3. Multithreading Programming Beginner Example
1. Creating a Thread
#include <stdio.h>
#include <pthread.h>
// Thread execution function
void* thread_function(void* arg) {
int value = *(int*)arg;
printf("Hello from thread! Value: %d\n", value);
return NULL;
}
int main() {
pthread_t thread; // Define thread identifier
int arg = 42; // Parameter passed to the thread
// Create thread
if (pthread_create(&thread, NULL, thread_function, &arg) != 0) {
perror("Failed to create thread");
return 1;
}
// Wait for thread to finish
pthread_join(thread, NULL);
printf("Main thread finished.\n");
return 0;
}
Compilation Command:
gcc -o thread_example thread_example.c -lpthread
Run Result:
Hello from thread! Value: 42
Main thread finished.

2. Thread Lifecycle
- Creation:
<span>pthread_create()</span> - Running: The thread executes the specified function
- Waiting:
<span>pthread_join()</span>waits for the thread to finish - Detached:
<span>pthread_detach()</span>releases thread resources - Termination:
<span>pthread_exit()</span>or the thread function returns
4. Thread Synchronization Mechanisms
1. Shared Resources and Data Races
When multiple threads access shared resources (such as global variables) simultaneously, it may lead to data inconsistency. For example:
#include <stdio.h>
#include <pthread.h>
int counter = 0;
void* increment_counter(void* arg) {
for (int i = 0; i < 100000; i++) {
counter++; // Unprotected shared resource
}
return NULL;
}
int main() {
pthread_t t1, t2;
pthread_create(&t1, NULL, increment_counter, NULL);
pthread_create(&t2, NULL, increment_counter, NULL);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
printf("Final counter value: %d\n", counter); // Expected value is 200000, but actual may be less
return 0;
}

Problem: <span>counter++</span> is a non-atomic operation (read-modify-write), and multiple threads operating simultaneously can lead to data races.
2. Mutex
A mutex is used to protect shared resources, ensuring that only one thread accesses them at a time.
#include <stdio.h>
#include <pthread.h>
int counter = 0;
pthread_mutex_t lock; // Define mutex
void* increment_counter(void* arg) {
for (int i = 0; i < 100000; i++) {
pthread_mutex_lock(&lock); // Lock
counter++;
pthread_mutex_unlock(&lock); // Unlock
}
return NULL;
}
int main() {
pthread_mutex_init(&lock, NULL); // Initialize mutex
pthread_t t1, t2;
pthread_create(&t1, NULL, increment_counter, NULL);
pthread_create(&t2, NULL, increment_counter, NULL);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
pthread_mutex_destroy(&lock); // Destroy mutex
printf("Final counter value: %d\n", counter); // Output 200000
return 0;
}

3. Condition Variable
A condition variable is used for inter-thread communication, waking up waiting threads when a certain condition is met.
Example: Producer-Consumer Model
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#define BUFFER_SIZE 5
int buffer[BUFFER_SIZE];
int count = 0;
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t not_empty = PTHREAD_COND_INITIALIZER;
pthread_cond_t not_full = PTHREAD_COND_INITIALIZER;
void* producer(void* arg) {
for (int i = 1; i <= 10; i++) {
pthread_mutex_lock(&lock);
while (count == BUFFER_SIZE) {
pthread_cond_wait(¬_full, &lock); // Wait when buffer is full
}
buffer[count++] = i;
printf("Produced: %d\n", i);
pthread_cond_signal(¬_empty); // Notify consumer
pthread_mutex_unlock(&lock);
usleep(100000); // Simulate production time
}
return NULL;
}
void* consumer(void* arg) {
for (int i = 1; i <= 10; i++) {
pthread_mutex_lock(&lock);
while (count == 0) {
pthread_cond_wait(¬_empty, &lock); // Wait when buffer is empty
}
int item = buffer[--count];
printf("Consumed: %d\n", item);
pthread_cond_signal(¬_full); // Notify producer
pthread_mutex_unlock(&lock);
usleep(100000); // Simulate consumption time
}
return NULL;
}
int main() {
pthread_t p, c;
pthread_create(&p, NULL, producer, NULL);
pthread_create(&c, NULL, consumer, NULL);
pthread_join(p, NULL);
pthread_join(c, NULL);
return 0;
}

‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧ END ‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧‧
Follow my public WeChat account and reply "C Language" to receive 300G of programming materials for free.
Feel free to like, share, recommend, and leave comments.