Creating Basic Threads in Linux
To implement mlutithreading in Linux, we use the POSIX threads library (pthread.h). Here's a basic example:
#include <iostream>
#include <pthread.h>
#include <unistd.h>
void* worker_function(void* data);
int main() {
pthread_t worker_id;
int thread_data = 5;
if(pthread_create(&worker_id, NULL, worker_function, (void*)&thread_data)) {
std::cerr << "Thread creation failed" << std::endl;
return 1;
}
sleep(2);
std::cout << "Main thread exiting" << std::endl;
return 0;
}
void* worker_function(void* data) {
int count = *((int*)data);
for(int i = 0; i < count; i++) {
sleep(1);
std::cout << "Worker thread executing" << std::endl;
}
return NULL;
}
Compile with: g++ -pthread program.cpp -o program
Synchroniizng Thread Exeuction
Using pthread_join ensures proper thread synchronization:
#include <iostream>
#include <pthread.h>
#include <cstring>
void* thread_task(void* input);
int main() {
pthread_t tid;
int param = 3;
void* result;
pthread_create(&tid, NULL, thread_task, (void*)¶m);
pthread_join(tid, &result);
std::cout << "Thread returned: " << (char*)result << std::endl;
return 0;
}
void* thread_task(void* input) {
int iterations = *((int*)input);
char* message = new char[50];
strcpy(message, "Thread completed successfully");
for(int i = 0; i < iterations; i++) {
sleep(1);
}
return (void*)message;
}
Thread Synchronization with Mutex
Preventing race conditions using mutex locks:
#include <iostream>
#include <pthread.h>
pthread_mutex_t counter_lock;
long shared_counter = 0;
void* increment_counter(void* arg) {
pthread_mutex_lock(&counter_lock);
for(int i = 0; i < 100000; i++) {
shared_counter++;
}
pthread_mutex_unlock(&counter_lock);
return NULL;
}
int main() {
pthread_t t1, t2;
pthread_mutex_init(&counter_lock, NULL);
pthread_create(&t1, NULL, increment_counter, NULL);
pthread_create(&t2, NULL, increment_counter, NULL);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
std::cout << "Final counter value: " << shared_counter << std::endl;
pthread_mutex_destroy(&counter_lock);
return 0;
}
Thread-Safe Server Implementation
A basic multithreaded server example:
#include <iostream>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <pthread.h>
#define MAX_CLIENTS 100
pthread_mutex_t client_lock;
int client_sockets[MAX_CLIENTS];
int client_count = 0;
void* handle_client(void* arg);
int main(int argc, char* argv[]) {
if(argc != 2) {
std::cerr << "Usage: " << argv[0] << " <port>" << std::endl;
return 1;
}
int server_fd = socket(AF_INET, SOCK_STREAM, 0);
sockaddr_in server_addr = {0};
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(atoi(argv[1]));
server_addr.sin_addr.s_addr = INADDR_ANY;
bind(server_fd, (sockaddr*)&server_addr, sizeof(server_addr));
listen(server_fd, 5);
pthread_mutex_init(&client_lock, NULL);
while(true) {
sockaddr_in client_addr;
socklen_t addr_len = sizeof(client_addr);
int client_fd = accept(server_fd, (sockaddr*)&client_addr, &addr_len);
pthread_mutex_lock(&client_lock);
client_sockets[client_count++] = client_fd;
pthread_mutex_unlock(&client_lock);
pthread_t client_thread;
pthread_create(&client_thread, NULL, handle_client, (void*)&client_fd);
pthread_detach(client_thread);
}
close(server_fd);
pthread_mutex_destroy(&client_lock);
return 0;
}
void* handle_client(void* arg) {
int client_fd = *((int*)arg);
char buffer[1024];
while(read(client_fd, buffer, sizeof(buffer)) > 0) {
// Process client request
}
pthread_mutex_lock(&client_lock);
for(int i = 0; i < client_count; i++) {
if(client_sockets[i] == client_fd) {
client_sockets[i] = client_sockets[--client_count];
break;
}
}
pthread_mutex_unlock(&client_lock);
close(client_fd);
return NULL;
}