In modern computing, multithreaded programming is a common technique that allows programs to execute multiple tasks simultaneously, thereby improving efficiency and responsiveness. In C, we can use the POSIX Threads (pthread) library to implement multithreaded programming. This article will introduce the fundamentals of multithreading in C and demonstrate with example code.
1. What is Multithreading?
Multithreading refers to the ability to concurrently execute multiple threads within the same process. Each thread has its own stack space and registers, but they share the process’s memory space. This makes data sharing straightforward, but it also introduces synchronization issues.
2. Introduction to the pthread Library
POSIX Threads (pthread) is an API for creating and managing multithreaded programs under the POSIX standard. It provides a set of functions for creating, terminating, synchronizing, and managing multiple execution flows.
Common Functions
<span>pthread_create</span>: Creates a new thread<span>pthread_join</span>: Waits for a specified thread to finish<span>pthread_exit</span>: Terminates the calling thread<span>pthread_mutex_lock</span>and<span>pthread_mutex_unlock</span>: Used for mutex locks to ensure safe access to shared resources
3. Creating a Simple Multithreaded Program
Below, we will demonstrate how to use the pthread library to create and manage multiple threads through a simple example.
Example Code: Print Numbers
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#define NUM_THREADS 5
// Function to be executed by each thread
void* print_numbers(void* threadid) {
long tid;
tid = (long)threadid;
printf("Thread %ld: ", tid);
for (int i = 0; i < 5; i++) {
printf("%d ", i + (int)tid * 5);
}
printf("\n");
pthread_exit(NULL);
}
int main() {
pthread_t threads[NUM_THREADS];
// Create multiple child threads
for (long t = 0; t < NUM_THREADS; t++) {
int rc = pthread_create(&threads[t], NULL, print_numbers, (void*)t);
if (rc) {
fprintf(stderr, "Error: Unable to create thread %ld\n", t);
exit(-1);
}
}
// Wait for all child threads to complete
for (int t = 0; t < NUM_THREADS; t++) {
pthread_join(threads[t], NULL);
}
return 0;
}
Program Analysis:
-
Include Header Files: We need to include
<span><stdio.h></span>and<span><stdlib.h></span>for input and output, and<span><pthread.h></span>to use POSIX multithreading features. -
Define Constants:
<span>NUM_THREADS</span>defines how many child threads we want to create. -
Define Child Thread Function:
- The function is named
<span>print_numbers</span>, which takes one parameter used to pass the thread ID. - It uses a loop to print a set of numbers corresponding to each thread.
- Finally, it calls
<span>pthread_exit(NULL)</span>to terminate the current thread.
Main Function:
- Declares an array to hold the IDs of the child threads.
- Uses a loop to call
<span>pthread_create()</span>to create new child threads, passing the appropriate parameters. If creation fails, it outputs an error message and exits the program.
Wait for All Child Threads to Complete:
- Again, using a loop, it calls
<span>pthread_join()</span>to wait for each child thread to complete its task, ensuring the main program does not exit prematurely.
4. Compilation and Execution
To compile this program, you need to link the pthread library. Enter the following command in the command line:
gcc -o multithread_example multithread_example.c -lpthread
Then run the generated executable:
./multithread_example
You should see output similar to the following, with each “Thread” followed by a different set of numbers, indicating they are running independently:
Thread 0: 0 1 2 3 Thread 1: 5 Thread ...
Conclusion
This article introduced the basic concepts of multithreading in C and how to implement them. By using the POSIX Threads library, we can easily create and manage multiple concurrently executing tasks. In practical applications, multithreading can significantly improve performance, but attention must also be paid to issues like data races. Therefore, when designing complex systems, it is essential to plan resource access strategies carefully, such as using mutexes for synchronization control. We hope this article helps you get started with multithreaded programming in C!