面试题答案
一键面试数据结构
- 共享内存结构体:
typedef struct {
// 假设大文件内容存储在此处,具体根据文件内容类型定义
char data[LARGE_FILE_SIZE];
// 用于同步操作的锁
pthread_mutex_t mutex;
} SharedData;
同步机制
- 互斥锁(Mutex):
- 在共享内存结构体中定义一个
pthread_mutex_t
类型的互斥锁,如上述代码中的mutex
。 - 在对共享文件数据进行读写操作前,使用
pthread_mutex_lock(&shared_data->mutex)
获取锁,操作完成后使用pthread_mutex_unlock(&shared_data->mutex)
释放锁。 - 示例代码片段:
- 在共享内存结构体中定义一个
SharedData *shared_data = (SharedData *)mmap(NULL, sizeof(SharedData), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (shared_data == MAP_FAILED) {
perror("mmap");
exit(EXIT_FAILURE);
}
// 初始化互斥锁
if (pthread_mutex_init(&shared_data->mutex, NULL) != 0) {
perror("pthread_mutex_init");
exit(EXIT_FAILURE);
}
// 读操作
pthread_mutex_lock(&shared_data->mutex);
// 进行读共享文件数据操作
pthread_mutex_unlock(&shared_data->mutex);
// 写操作
pthread_mutex_lock(&shared_data->mutex);
// 进行写共享文件数据操作
pthread_mutex_unlock(&shared_data->mutex);
异常处理策略
- mmap 错误:
mmap
函数返回MAP_FAILED
时,使用perror
打印错误信息,并根据情况选择退出程序或进行更复杂的错误恢复逻辑。如上述代码中:
if (shared_data == MAP_FAILED) {
perror("mmap");
exit(EXIT_FAILURE);
}
- 互斥锁操作错误:
pthread_mutex_init
、pthread_mutex_lock
、pthread_mutex_unlock
等函数返回非0值时,表示操作失败。同样使用perror
打印错误信息,并根据情况处理。例如:
if (pthread_mutex_init(&shared_data->mutex, NULL) != 0) {
perror("pthread_mutex_init");
exit(EXIT_FAILURE);
}
- 文件操作错误:
- 在打开文件(假设使用
open
函数)时,如果返回 -1,表示打开文件失败,使用perror
打印错误信息并处理。
- 在打开文件(假设使用
int fd = open("large_file", O_RDWR);
if (fd == -1) {
perror("open");
exit(EXIT_FAILURE);
}
- munmap 错误:
- 在程序结束时,通常需要使用
munmap
解除映射,如果munmap
返回 -1,表示解除映射失败,使用perror
打印错误信息。
- 在程序结束时,通常需要使用
if (munmap(shared_data, sizeof(SharedData)) == -1) {
perror("munmap");
exit(EXIT_FAILURE);
}
完整示例代码:
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <pthread.h>
#include <unistd.h>
#define LARGE_FILE_SIZE 1024 * 1024
typedef struct {
char data[LARGE_FILE_SIZE];
pthread_mutex_t mutex;
} SharedData;
int main() {
int fd = open("large_file", O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
if (fd == -1) {
perror("open");
return EXIT_FAILURE;
}
if (lseek(fd, LARGE_FILE_SIZE - 1, SEEK_SET) == -1) {
perror("lseek");
close(fd);
return EXIT_FAILURE;
}
if (write(fd, "", 1) != 1) {
perror("write");
close(fd);
return EXIT_FAILURE;
}
SharedData *shared_data = (SharedData *)mmap(NULL, sizeof(SharedData), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (shared_data == MAP_FAILED) {
perror("mmap");
close(fd);
return EXIT_FAILURE;
}
if (pthread_mutex_init(&shared_data->mutex, NULL) != 0) {
perror("pthread_mutex_init");
munmap(shared_data, sizeof(SharedData));
close(fd);
return EXIT_FAILURE;
}
// 示例进程操作
// 读操作
pthread_mutex_lock(&shared_data->mutex);
// 进行读共享文件数据操作
pthread_mutex_unlock(&shared_data->mutex);
// 写操作
pthread_mutex_lock(&shared_data->mutex);
// 进行写共享文件数据操作
pthread_mutex_unlock(&shared_data->mutex);
if (pthread_mutex_destroy(&shared_data->mutex) != 0) {
perror("pthread_mutex_destroy");
}
if (munmap(shared_data, sizeof(SharedData)) == -1) {
perror("munmap");
}
close(fd);
return 0;
}