MST

星途 面试题库

面试题:C语言非阻塞I/O错误处理在并发场景中的应用

在多线程或多进程并发执行非阻塞I/O操作的场景下,如何处理由于资源竞争导致的错误?请举例说明如何使用互斥锁、信号量等机制配合C语言的非阻塞I/O错误处理,以确保程序的正确性和稳定性。
10.4万 热度难度
编程语言C

知识考点

AI 面试

面试题答案

一键面试

使用互斥锁处理资源竞争

  1. 原理:互斥锁(Mutex)用于保证在同一时间只有一个线程或进程能够访问共享资源,从而避免资源竞争。
  2. C语言示例
#include <stdio.h>
#include <pthread.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>

pthread_mutex_t mutex;
int fd;

void* read_file(void* arg) {
    pthread_mutex_lock(&mutex);
    char buffer[1024];
    // 设置为非阻塞I/O
    fcntl(fd, F_SETFL, O_NONBLOCK);
    ssize_t bytes_read = read(fd, buffer, sizeof(buffer));
    if (bytes_read == -1 && errno == EAGAIN) {
        // 处理非阻塞I/O没有数据可读的情况
        printf("No data available yet\n");
    } else if (bytes_read > 0) {
        buffer[bytes_read] = '\0';
        printf("Read data: %s\n", buffer);
    }
    pthread_mutex_unlock(&mutex);
    return NULL;
}

int main() {
    pthread_t thread;
    pthread_mutex_init(&mutex, NULL);
    fd = open("test.txt", O_RDONLY);
    if (fd == -1) {
        perror("open");
        return 1;
    }

    pthread_create(&thread, NULL, read_file, NULL);
    pthread_join(thread, NULL);

    close(fd);
    pthread_mutex_destroy(&mutex);
    return 0;
}

使用信号量处理资源竞争

  1. 原理:信号量(Semaphore)可以控制同时访问共享资源的线程或进程数量。它通过一个计数器来实现,当计数器大于0时,线程或进程可以获取信号量(计数器减1)并访问资源,当计数器为0时,获取操作将阻塞。
  2. C语言示例
#include <stdio.h>
#include <pthread.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <semaphore.h>

sem_t sem;
int fd;

void* read_file(void* arg) {
    sem_wait(&sem);
    char buffer[1024];
    // 设置为非阻塞I/O
    fcntl(fd, F_SETFL, O_NONBLOCK);
    ssize_t bytes_read = read(fd, buffer, sizeof(buffer));
    if (bytes_read == -1 && errno == EAGAIN) {
        // 处理非阻塞I/O没有数据可读的情况
        printf("No data available yet\n");
    } else if (bytes_read > 0) {
        buffer[bytes_read] = '\0';
        printf("Read data: %s\n", buffer);
    }
    sem_post(&sem);
    return NULL;
}

int main() {
    pthread_t thread;
    sem_init(&sem, 0, 1);
    fd = open("test.txt", O_RDONLY);
    if (fd == -1) {
        perror("open");
        return 1;
    }

    pthread_create(&thread, NULL, read_file, NULL);
    pthread_join(thread, NULL);

    close(fd);
    sem_destroy(&sem);
    return 0;
}

总结

  • 在多线程或多进程并发执行非阻塞I/O操作时,互斥锁和信号量是有效处理资源竞争的机制。
  • 互斥锁适合于一次只允许一个线程或进程访问共享资源的场景,而信号量则更灵活,可以控制同时访问资源的数量。
  • 在非阻塞I/O错误处理方面,通过检查errno是否为EAGAIN来判断是否没有数据可读,从而进行相应的处理,确保程序的正确性和稳定性。