多线程编程是现代程序提高并发性能的重要手段。C语言通过pthread库提供强大的多线程支持,本文详细介绍线程创建、同步机制与线程池的实现。
线程基础概念
线程是程序执行的最小单位,同一进程内的线程共享进程的地址空间、全局变量和打开的文件描述符。与进程相比,线程创建和切换的开销更小。
线程创建与结束
使用pthread_create创建新线程,pthread_join等待线程结束:
#include
#include
#include
void* thread_worker(void *arg) {
int *num = (int*)arg;
printf("Thread running with arg: %d\n", *num);
return NULL;
}
int main(void) {
pthread_t tid;
int param = 42;
/* 创建新线程 */
if (pthread_create(&tid, NULL, thread_worker, ¶m) != 0) {
perror("pthread_create");
return 1;
}
/* 等待线程结束 */
pthread_join(tid, NULL);
printf("Thread finished\n");
return 0;
}
互斥锁
互斥锁用于保护共享资源,防止多个线程同时访问造成数据竞争:
typedef struct {
int counter;
pthread_mutex_t mutex;
} Counter;
void counter_inc(Counter *c) {
pthread_mutex_lock(&c->mutex); /* 加锁 */
c->counter++;
pthread_mutex_unlock(&c->mutex); /* 解锁 */
}
/* 初始化互斥锁 */
Counter c = {0, PTHREAD_MUTEX_INITIALIZER};
条件变量
条件变量用于线程间的同步,允许线程等待某个条件成立:
typedef struct {
int ready;
pthread_mutex_t mutex;
pthread_cond_t cond;
} Context;
/* 等待条件 */
void wait_ready(Context *ctx) {
pthread_mutex_lock(&ctx->mutex);
while (!ctx->ready) {
pthread_cond_wait(&ctx->cond, &ctx->mutex);
}
pthread_mutex_unlock(&ctx->mutex);
}
/* 发送信号 */
void signal_ready(Context *ctx) {
pthread_mutex_lock(&ctx->mutex);
ctx->ready = 1;
pthread_cond_signal(&ctx->cond);
pthread_mutex_unlock(&ctx->mutex);
}
读写锁
读写锁适合读多写少的场景,允许多个线程同时读,但写操作需要独占:
typedef struct {
int data;
pthread_rwlock_t rwlock;
} SharedData;
/* 读操作 */
int read_data(SharedData *sd) {
int val;
pthread_rwlock_rdlock(&sd->rwlock);
val = sd->data;
pthread_rwlock_unlock(&sd->rwlock);
return val;
}
/* 写操作 */
void write_data(SharedData *sd, int val) {
pthread_rwlock_wrlock(&sd->rwlock);
sd->data = val;
pthread_rwlock_unlock(&sd->rwlock);
}
线程池实现
线程池预先创建一组工作线程,避免频繁创建销毁线程的开销:
typedef struct {
pthread_mutex_t mutex;
pthread_cond_t cond;
pthread_t *workers;
void *(*task_fn)(void*);
void *task_arg;
int shutdown;
int count;
} ThreadPool;
void* worker_loop(void *arg) {
ThreadPool *pool = (ThreadPool*)arg;
while(1) {
pthread_mutex_lock(&pool->mutex);
while (pool->task_fn == NULL && !pool->shutdown) {
pthread_cond_wait(&pool->cond, &pool->mutex);
}
if (pool->shutdown) break;
void *(*fn)(void*) = pool->task_fn;
void *arg = pool->task_arg;
pool->task_fn = NULL;
pthread_mutex_unlock(&pool->mutex);
fn(arg);
}
pthread_mutex_unlock(&pool->mutex);
return NULL;
}
注意事项
多线程编程需要注意:避免死锁(按相同顺序加锁)、减少锁粒度、使用线程安全函数。
总结
- pthread库提供完整的线程支持
- 互斥锁用于保护共享资源
- 条件变量实现线程同步
- 读写锁适合读多写少场景
- 线程池提高频繁任务的执行效率