MST

星途 面试题库

面试题:C语言在Linux下利用文件描述符实现并发读写

在Linux系统中,使用C语言编写一个程序,利用文件描述符实现对一个大文件的并发读写。要求开启两个线程,一个线程负责从文件中读取数据,另一个线程负责将特定数据写入该文件。请描述整体设计思路,并给出关键代码部分以及对同步机制(如互斥锁等)的运用说明。
10.9万 热度难度
编程语言C

知识考点

AI 面试

面试题答案

一键面试

设计思路

  1. 文件描述符:通过 open 系统调用获取文件的文件描述符,以便在两个线程中对同一个文件进行操作。
  2. 线程:使用POSIX线程库(pthread)创建两个线程,一个线程执行读操作,另一个线程执行写操作。
  3. 同步机制:为了避免读写冲突,使用互斥锁(pthread_mutex_t)来保护对文件的访问。读线程和写线程在访问文件前都需要先获取互斥锁,操作完成后释放互斥锁。

关键代码部分

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>

#define FILE_NAME "big_file.txt"
#define WRITE_BUFFER_SIZE 1024
#define READ_BUFFER_SIZE 1024

// 定义全局变量
int file_descriptor;
pthread_mutex_t mutex;

// 写线程函数
void* write_thread_function(void* arg) {
    char write_buffer[WRITE_BUFFER_SIZE] = "This is data to be written.\n";
    ssize_t write_bytes;

    // 加锁
    pthread_mutex_lock(&mutex);
    lseek(file_descriptor, 0, SEEK_END); // 移动到文件末尾
    write_bytes = write(file_descriptor, write_buffer, strlen(write_buffer));
    if (write_bytes == -1) {
        perror("Write error");
    }
    // 解锁
    pthread_mutex_unlock(&mutex);

    pthread_exit(NULL);
}

// 读线程函数
void* read_thread_function(void* arg) {
    char read_buffer[READ_BUFFER_SIZE];
    ssize_t read_bytes;

    // 加锁
    pthread_mutex_lock(&mutex);
    lseek(file_descriptor, 0, SEEK_SET); // 移动到文件开头
    read_bytes = read(file_descriptor, read_buffer, READ_BUFFER_SIZE - 1);
    if (read_bytes == -1) {
        perror("Read error");
    } else {
        read_buffer[read_bytes] = '\0';
        printf("Read data: %s", read_buffer);
    }
    // 解锁
    pthread_mutex_unlock(&mutex);

    pthread_exit(NULL);
}

主函数及同步机制运用说明

int main() {
    pthread_t write_thread, read_thread;

    // 初始化互斥锁
    if (pthread_mutex_init(&mutex, NULL) != 0) {
        perror("Mutex initialization failed");
        return 1;
    }

    // 打开文件
    file_descriptor = open(FILE_NAME, O_RDWR | O_CREAT, 0666);
    if (file_descriptor == -1) {
        perror("File open error");
        pthread_mutex_destroy(&mutex);
        return 1;
    }

    // 创建写线程
    if (pthread_create(&write_thread, NULL, write_thread_function, NULL) != 0) {
        perror("Write thread creation failed");
        close(file_descriptor);
        pthread_mutex_destroy(&mutex);
        return 1;
    }

    // 创建读线程
    if (pthread_create(&read_thread, NULL, read_thread_function, NULL) != 0) {
        perror("Read thread creation failed");
        pthread_cancel(write_thread);
        close(file_descriptor);
        pthread_mutex_destroy(&mutex);
        return 1;
    }

    // 等待线程结束
    pthread_join(write_thread, NULL);
    pthread_join(read_thread, NULL);

    // 关闭文件描述符和销毁互斥锁
    close(file_descriptor);
    pthread_mutex_destroy(&mutex);

    return 0;
}
  1. 互斥锁初始化:在 main 函数中,使用 pthread_mutex_init 初始化互斥锁。
  2. 加锁与解锁:在读写线程函数中,分别在文件操作前使用 pthread_mutex_lock 加锁,操作完成后使用 pthread_mutex_unlock 解锁,确保同一时间只有一个线程可以访问文件,避免数据竞争。
  3. 线程创建与等待:在 main 函数中创建读写线程,并使用 pthread_join 等待线程执行完毕。
  4. 资源清理:在程序结束前关闭文件描述符并销毁互斥锁,释放资源。