目录
一. 背景
二. 高效同步机制实现
1. 轻量级锁(自旋锁)与互斥锁
1.1 轻量级锁(自旋锁):
1.2 互斥锁
2. 条件变量减少忙等待
二、优化阻塞处理的实现
1. 分离阻塞操作到独立线程
2. 信号量与异步 I/O 提升 CPU 利用率
2.1 信号量控制并发资源
2.2 异步 I/O 模型
三、策略总结
一. 背景
在多线程编程中,同步与资源管理是保证程序正确性和性能的核心问题。线程同步用于协调多个线程对共享资源的访问,而资源管理则确保资源(如内存、文件、网络连接)的合理分配与释放。本文通过实例详解常见同步机制与资源管理策略。
二. 高效同步机制实现
1. 轻量级锁(自旋锁)与互斥锁
1.1 轻量级锁(自旋锁):
-
适用场景:保护执行时间极短的临界区(如计数器递增、标志位修改。
-
实现原理:通过 CAS(Compare-And-Swap)原子操作尝试获取锁,失败时自旋而非阻塞线程,避免上下文切换开销。
示例(基于 GCC 原子操作模拟自旋锁):
#include <stdatomic.h>
#include <stdbool.h>typedef struct {atomic_bool locked;
} spinlock_t;void spinlock_init(spinlock_t* lock) {atomic_init(&lock->locked, false);
}void spinlock_lock(spinlock_t* lock) {// 自旋直到成功获取锁while (atomic_exchange(&lock->locked, true)) {// 自旋等待(空循环)}
}void spinlock_unlock(spinlock_t* lock) {atomic_store(&lock->locked, false);
}// ------------------ 使用示例 ------------------
spinlock_t counter_lock;
int counter = 0;void* thread_func(void* arg) {spinlock_lock(&counter_lock);counter++; // 临界区操作spinlock_unlock(&counter_lock);return NULL;
}
1.2 互斥锁
- 适用场景:临界区执行时间较长(如文件读写、数据库操作)。
- 示例(POSIX 线程互斥锁):
#include<pthread.h>pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
int share_data = 0;void *thread_func(void *arg)
{pthread_mutex_lock(&mutex);...//TO DO;长耗时的操作如写入文件share_data += 10;...pthread_mutex_unlock(&mutex);return NULL;
}
2. 条件变量减少忙等待
-
作用:通过事件通知机制唤醒等待线程,避免 CPU 空转。
-
典型场景:生产者-消费者模型中协调缓冲区状态。
-
示例(生产者-消费者模型):
#include <pthread.h> #include <stdbool.h>#define BUFFER_SIZE 5pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t cond_producer = PTHREAD_COND_INITIALIZER; pthread_cond_t cond_consumer = PTHREAD_COND_INITIALIZER;int count = 0; int buffer[BUFFER_SIZE];void *prouducer(void *arg) {for(int i = 0; i < 10; i++){pthread_mutex_lock(&mutex);while(count == BUFFER_SIZE){pthread_cond_wait(&cond_producer, &mutex);}buffer[count++] = i;printf("produced:%d\n",i);pthread_cond_signal(&cond_consumer);pthread_mutex_unlock(&mutex);}return NULL; }void *consumer(void *arg) {for(int i=0,i<10;i++){pthread_mutex_lock(&mutex);while(count == 0){pthread_cond_wait(&cond_consumer, &mutex);}int item = buffer[--count];printf("consumer:%d\n",item);pthread_cond_signal(&cond_proudcer);pthread_mutex_unlock();}return NULL; }
二、优化阻塞处理的实现
1. 分离阻塞操作到独立线程
-
原理:将阻塞 I/O 分配到独立线程,主线程继续处理非阻塞任务。
-
示例(创建独立线程处理文件读取):
#include <pthread.h> #include <stido.h> #include <unistd.h>void *file_write(void *arg) {FILE *fp = NULL;fp = fopen("data.txt", "r");if (fp){char buffer[1024];fread(buffer, sizeof(buffer), fp);printf("read=%s",buffer);fclose(fp);}return NULL; }int main(void) {pthread_t tid;pthread_create(&tid, NULL, file_write, NULL);printf("main task");pthread_join(tid,NULL);return 0; }
2. 信号量与异步 I/O 提升 CPU 利用率
2.1 信号量控制并发资源
-
用途:限制同时访问资源的线程数量(如数据库连接池)。
-
示例(POSIX 信号量)
#include<semaphore.h> #include<pthread.h> #include<stdio.h>#define MAX_CONNECT_CNT 3 sem_t db_sem;void *db_process(void *arg) {sem_wait(&db_sem);printf("pthread:%ld\n", pthread_self());sleep(1);sem_post(&db_sem);return NULL; }int main(void) {pthread_t tid[5];sem_init(&db_sem, 0, MAX_CONNECT_CNT);for(int i = 0;i<5; i++) {pthread_create(&tid[i], NULL, db_process, NULL);pthread_join(tid[i],NULL)sem_destory(&db_sem);}return 0; }
2.2 异步 I/O 模型
-
原理:通过非阻塞 I/O 和回调机制分离计算与阻塞操作。
-
示例(Linux AIO 基本使用)
#include <aio.h> #include <fcntl.h> #include <unistd.h> void aio_callback(sigval_t sigval) {struct aiocb *req = (struct aiocb*)sigval.sival_ptr; printf("Async read completed: %s\n", (char*)req->aio_buf); }int main() { char buffer[1024]; struct aiocb req = {0}; int fd = open("data.txt", O_RDONLY); req.aio_fildes = fd;req.aio_buf = buffer; req.aio_nbytes = sizeof(buffer); req.aio_offset = 0; req.aio_sigevent.sigev_notify = SIGEV_THREAD; req.aio_sigevent.sigev_notify_function = aio_callback; req.aio_sigevent.sigev_value.sival_ptr = &req; aio_read(&req); // 发起异步读操作 // 主线程继续执行其他任务 printf("Main thread processing...\n"); sleep(2); // 等待异步操作完成 close(fd);return 0; }
三、策略总结
场景 | 技术方案 | 核心实现 |
---|---|---|
短期临界区保护 | 自旋锁(原子操作) | atomic_compare_exchange |
长耗时同步任务 | 互斥锁 + 条件变量 | pthread_mutex_lock /pthread_cond_wait |
高并发阻塞操作 | 独立线程池 + 信号量 | pthread_create /sem_wait |
非阻塞 I/O 分离 | 异步 I/O 模型 | aio_read + 回调机制 |
通过合理选择同步机制和异步模型,可显著提升多线程程序的吞吐量与响应速度。