面试题答案
一键面试避免资源竞争的方法
- 互斥锁(Mutex):用于保护共享资源,在访问共享资源前加锁,访问结束后解锁,确保同一时间只有一个线程能访问该资源。
- 条件变量(Condition Variable):与互斥锁配合使用,线程可以等待某个条件满足后再继续执行,避免无效的循环等待。
- 读写锁(Read - Write Lock):如果共享资源主要是读操作,可使用读写锁,允许多个线程同时读,但写操作时需独占,以保证数据一致性。
代码示例
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <aio.h>
#define BUFFER_SIZE 1024
// 共享资源
char buffer[BUFFER_SIZE];
pthread_mutex_t mutex;
pthread_cond_t cond;
// 模拟异步I/O完成的标志
int io_completed = 0;
// 异步I/O控制块
struct aiocb my_aiocb;
// 线程函数,执行异步I/O
void* async_io_thread(void* arg) {
// 初始化异步I/O控制块
memset(&my_aiocb, 0, sizeof(struct aiocb));
my_aiocb.aio_fildes = STDIN_FILENO;
my_aiocb.aio_buf = buffer;
my_aiocb.aio_nbytes = BUFFER_SIZE;
my_aiocb.aio_offset = 0;
// 发起异步读操作
if (aio_read(&my_aiocb) == -1) {
perror("aio_read");
pthread_exit(NULL);
}
// 等待异步I/O完成
while (aio_error(&my_aiocb) == EINPROGRESS);
// 获取锁
pthread_mutex_lock(&mutex);
io_completed = 1;
// 通知等待的线程
pthread_cond_signal(&cond);
// 释放锁
pthread_mutex_unlock(&mutex);
pthread_exit(NULL);
}
// 主线程,处理数据
int main() {
pthread_t tid;
// 初始化互斥锁和条件变量
pthread_mutex_init(&mutex, NULL);
pthread_cond_init(&cond, NULL);
// 创建线程执行异步I/O
if (pthread_create(&tid, NULL, async_io_thread, NULL) != 0) {
perror("pthread_create");
return EXIT_FAILURE;
}
// 获取锁
pthread_mutex_lock(&mutex);
// 等待异步I/O完成
while (!io_completed) {
pthread_cond_wait(&cond, &mutex);
}
// 释放锁
pthread_mutex_unlock(&mutex);
// 处理数据
printf("Data read from async I/O: %s\n", buffer);
// 清理
pthread_mutex_destroy(&mutex);
pthread_cond_destroy(&cond);
pthread_join(tid, NULL);
return EXIT_SUCCESS;
}
在上述代码中:
- 互斥锁
mutex
:用于保护io_completed
这个共享资源,确保在修改和读取它时不会出现竞争。 - 条件变量
cond
:主线程通过pthread_cond_wait
等待异步I/O完成的通知,避免了无效的循环等待,提高了效率。 - 异步I/O线程在完成I/O操作后,通过
pthread_cond_signal
通知主线程。