MST

星途 面试题库

面试题:C语言中信号量同步机制基础

在Linux环境下使用C语言实现一个简单的生产者 - 消费者模型,其中利用信号量来同步生产者和消费者的操作。请简述实现思路,并给出关键代码片段。
13.5万 热度难度
编程语言C

知识考点

AI 面试

面试题答案

一键面试

实现思路

  1. 共享数据结构:定义一个共享缓冲区用于生产者生产数据和消费者消费数据。
  2. 信号量:使用信号量来控制对共享缓冲区的访问。一个信号量用于表示缓冲区中的空闲槽位(empty),另一个用于表示缓冲区中的已占用槽位(full),还需要一个互斥信号量(mutex)来保证对共享缓冲区的互斥访问。
  3. 生产者:生产者线程获取empty信号量(表示有空闲槽位),然后获取mutex互斥信号量以安全访问共享缓冲区,生产数据放入缓冲区,释放mutex,再释放full信号量(表示有新数据)。
  4. 消费者:消费者线程获取full信号量(表示有数据),获取mutex互斥信号量以安全访问共享缓冲区,从缓冲区消费数据,释放mutex,再释放empty信号量(表示有空闲槽位)。

关键代码片段

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>

#define BUFFER_SIZE 5
int buffer[BUFFER_SIZE];
int in = 0;
int out = 0;

sem_t empty;
sem_t full;
sem_t mutex;

// 生产者函数
void* producer(void* arg) {
    int item = 0;
    while (1) {
        sem_wait(&empty);  // 等待缓冲区有空闲槽位
        sem_wait(&mutex);  // 进入临界区
        buffer[in] = item;
        printf("Produced: %d\n", item);
        in = (in + 1) % BUFFER_SIZE;
        sem_post(&mutex);  // 离开临界区
        sem_post(&full);   // 通知缓冲区有新数据
        item++;
    }
    return NULL;
}

// 消费者函数
void* consumer(void* arg) {
    while (1) {
        sem_wait(&full);   // 等待缓冲区有数据
        sem_wait(&mutex);  // 进入临界区
        int item = buffer[out];
        printf("Consumed: %d\n", item);
        out = (out + 1) % BUFFER_SIZE;
        sem_post(&mutex);  // 离开临界区
        sem_post(&empty);  // 通知缓冲区有空闲槽位
    }
    return NULL;
}

int main() {
    pthread_t producer_thread, consumer_thread;

    sem_init(&empty, 0, BUFFER_SIZE);
    sem_init(&full, 0, 0);
    sem_init(&mutex, 0, 1);

    pthread_create(&producer_thread, NULL, producer, NULL);
    pthread_create(&consumer_thread, NULL, consumer, NULL);

    pthread_join(producer_thread, NULL);
    pthread_join(consumer_thread, NULL);

    sem_destroy(&empty);
    sem_destroy(&full);
    sem_destroy(&mutex);

    return 0;
}