MST

星途 面试题库

面试题:C语言在Linux多进程服务器模型中如何处理共享资源

在Linux环境下,使用C语言设计多进程服务器模型时,经常会涉及到共享资源的访问。请描述一下可能存在哪些共享资源,以及如何使用C语言的相关机制(如信号量等)来避免竞态条件,保证共享资源的安全访问。
42.6万 热度难度
编程语言C

知识考点

AI 面试

面试题答案

一键面试

可能存在的共享资源

  1. 内存区域:如共享内存段,多个进程可以映射到同一块物理内存,用于数据的快速交换和共享。例如,在服务器中,可能多个子进程需要读取和修改某些配置信息,这些信息可以存储在共享内存中。
  2. 文件:多个进程可能需要同时对同一个文件进行读写操作。比如日志文件,多个进程都可能向其中写入日志信息。
  3. 网络套接字:在服务器模型中,多个进程可能需要使用同一个监听套接字来接受客户端连接。例如,主进程创建监听套接字后,fork出多个子进程,这些子进程都可能需要从该监听套接字接受新的连接。

使用C语言相关机制避免竞态条件

  1. 信号量
    • 原理:信号量是一个整型变量,它通过计数器来控制对共享资源的访问。当信号量的值大于0时,进程可以获取信号量(将计数器减1),从而访问共享资源;当信号量的值为0时,进程会阻塞,直到信号量的值大于0。
    • 示例代码
#include <stdio.h>
#include <stdlib.h>
#include <semaphore.h>
#include <pthread.h>
#include <unistd.h>

sem_t sem;
int shared_variable = 0;

void* increment(void* arg) {
    for (int i = 0; i < 1000; i++) {
        sem_wait(&sem);
        shared_variable++;
        sem_post(&sem);
    }
    return NULL;
}

int main() {
    sem_init(&sem, 0, 1);

    pthread_t thread1, thread2;
    pthread_create(&thread1, NULL, increment, NULL);
    pthread_create(&thread2, NULL, increment, NULL);

    pthread_join(thread1, NULL);
    pthread_join(thread2, NULL);

    sem_destroy(&sem);
    printf("Final value of shared_variable: %d\n", shared_variable);
    return 0;
}
  1. 互斥锁(本质也是一种特殊的二元信号量)
    • 原理:互斥锁只有两种状态(锁定和解锁),它用于保证在同一时间只有一个进程能够访问共享资源。当一个进程获取了互斥锁(将其锁定),其他进程就无法获取,直到该进程释放互斥锁(解锁)。
    • 示例代码
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
int shared_variable = 0;

void* increment(void* arg) {
    for (int i = 0; i < 1000; i++) {
        pthread_mutex_lock(&mutex);
        shared_variable++;
        pthread_mutex_unlock(&mutex);
    }
    return NULL;
}

int main() {
    pthread_t thread1, thread2;
    pthread_create(&thread1, NULL, increment, NULL);
    pthread_create(&thread2, NULL, increment, NULL);

    pthread_join(thread1, NULL);
    pthread_join(thread2, NULL);

    pthread_mutex_destroy(&mutex);
    printf("Final value of shared_variable: %d\n", shared_variable);
    return 0;
}
  1. 读写锁
    • 原理:读写锁区分了读操作和写操作。允许多个进程同时进行读操作(因为读操作不会修改共享资源,不会产生竞态条件),但只允许一个进程进行写操作,并且在写操作时不允许有其他进程进行读或写操作。
    • 示例代码
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>

pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZER;
int shared_variable = 0;

void* read_func(void* arg) {
    pthread_rwlock_rdlock(&rwlock);
    printf("Reading value: %d\n", shared_variable);
    pthread_rwlock_unlock(&rwlock);
    return NULL;
}

void* write_func(void* arg) {
    pthread_rwlock_wrlock(&rwlock);
    shared_variable++;
    printf("Writing value: %d\n", shared_variable);
    pthread_rwlock_unlock(&rwlock);
    return NULL;
}

int main() {
    pthread_t read_thread, write_thread;
    pthread_create(&read_thread, NULL, read_func, NULL);
    pthread_create(&write_thread, NULL, write_func, NULL);

    pthread_join(read_thread, NULL);
    pthread_join(write_thread, NULL);

    pthread_rwlock_destroy(&rwlock);
    return 0;
}