MST

星途 面试题库

面试题:C语言中Linux多线程服务器资源竞争的常见场景及解决思路

在Linux C语言多线程服务器开发中,常常会出现资源竞争问题。请举例说明至少两种常见的资源竞争场景,并简要阐述对应的一般解决思路。
12.7万 热度难度
编程语言C

知识考点

AI 面试

面试题答案

一键面试

常见资源竞争场景及解决思路

  1. 共享内存竞争
    • 场景举例:多个线程同时访问和修改同一块共享内存区域。比如,一个线程向共享内存写入数据,另一个线程同时读取该共享内存,可能导致读取到的数据不完整或写入的数据出现错误。
    • 解决思路:使用互斥锁(mutex)。在访问共享内存前,线程先获取互斥锁,访问结束后释放互斥锁。这样同一时间只有一个线程能访问共享内存,避免竞争。示例代码如下:
#include <pthread.h>
#include <stdio.h>

pthread_mutex_t mutex;
int shared_variable;

void* thread_function(void* arg) {
    pthread_mutex_lock(&mutex);
    shared_variable++;
    printf("Thread incremented shared_variable to %d\n", shared_variable);
    pthread_mutex_unlock(&mutex);
    return NULL;
}

int main() {
    pthread_t thread;
    shared_variable = 0;
    pthread_mutex_init(&mutex, NULL);

    if (pthread_create(&thread, NULL, thread_function, NULL) != 0) {
        perror("pthread_create");
        return 1;
    }

    if (pthread_join(thread, NULL) != 0) {
        perror("pthread_join");
        return 2;
    }

    pthread_mutex_destroy(&mutex);
    return 0;
}
  1. 文件I/O竞争
    • 场景举例:多个线程同时对同一个文件进行读写操作。例如,一个线程在写入文件的过程中,另一个线程开始读取文件,可能造成文件内容混乱或数据丢失。
    • 解决思路:同样可以使用互斥锁。在进行文件操作前获取互斥锁,操作完成后释放。也可以使用文件锁(如flock函数)。示例代码使用互斥锁如下:
#include <pthread.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>

pthread_mutex_t mutex;
const char* filename = "test.txt";

void* write_to_file(void* arg) {
    pthread_mutex_lock(&mutex);
    int fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0644);
    if (fd == -1) {
        perror("open");
        pthread_mutex_unlock(&mutex);
        return NULL;
    }
    const char* data = "This is some data written by a thread.\n";
    if (write(fd, data, strlen(data)) == -1) {
        perror("write");
    }
    close(fd);
    pthread_mutex_unlock(&mutex);
    return NULL;
}

void* read_from_file(void* arg) {
    pthread_mutex_lock(&mutex);
    int fd = open(filename, O_RDONLY);
    if (fd == -1) {
        perror("open");
        pthread_mutex_unlock(&mutex);
        return NULL;
    }
    char buffer[1024];
    ssize_t bytes_read = read(fd, buffer, sizeof(buffer) - 1);
    if (bytes_read == -1) {
        perror("read");
    } else {
        buffer[bytes_read] = '\0';
        printf("Read from file: %s", buffer);
    }
    close(fd);
    pthread_mutex_unlock(&mutex);
    return NULL;
}

int main() {
    pthread_t write_thread, read_thread;
    pthread_mutex_init(&mutex, NULL);

    if (pthread_create(&write_thread, NULL, write_to_file, NULL) != 0) {
        perror("pthread_create");
        return 1;
    }

    if (pthread_create(&read_thread, NULL, read_from_file, NULL) != 0) {
        perror("pthread_create");
        return 1;
    }

    if (pthread_join(write_thread, NULL) != 0) {
        perror("pthread_join");
        return 2;
    }

    if (pthread_join(read_thread, NULL) != 0) {
        perror("pthread_join");
        return 2;
    }

    pthread_mutex_destroy(&mutex);
    return 0;
}
  1. 全局变量竞争
    • 场景举例:多个线程对全局变量进行读写操作。例如,一个计算任务线程和一个统计任务线程同时访问全局的计算结果变量,可能导致统计数据不准确。
    • 解决思路:利用互斥锁保护对全局变量的访问。或者在某些情况下,如果全局变量只涉及读操作(即线程安全的只读情况),可以不使用锁,但一旦有写操作,必须加锁。示例代码如下:
#include <pthread.h>
#include <stdio.h>

pthread_mutex_t mutex;
int global_variable;

void* increment_global(void* arg) {
    pthread_mutex_lock(&mutex);
    global_variable++;
    printf("Thread incremented global_variable to %d\n", global_variable);
    pthread_mutex_unlock(&mutex);
    return NULL;
}

int main() {
    pthread_t thread;
    global_variable = 0;
    pthread_mutex_init(&mutex, NULL);

    if (pthread_create(&thread, NULL, increment_global, NULL) != 0) {
        perror("pthread_create");
        return 1;
    }

    if (pthread_join(thread, NULL) != 0) {
        perror("pthread_join");
        return 2;
    }

    pthread_mutex_destroy(&mutex);
    return 0;
}