📌  相关文章
📜  教资会网络 | UGC-NET CS 2017 年 11 月 – III |问题 27(1)

📅  最后修改于: 2023-12-03 14:54:51.589000             🧑  作者: Mango

UGC-NET CS 2017 年 11 月 – III | 问题 27

本题是一道关于操作系统的问题,主要考察进程同步和通信的相关概念及技术。

问题描述

以下程序片段使用的是信号量实现进程间通信的同步机制,请回答程序的输出结果。

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

sem_t sem;
int buffer = 0;

void *producer(void *arg) {
    while (1) {
        sleep(1);
        sem_wait(&sem);
        buffer++;
        printf("[Producer] buffer value: %d\n", buffer);
        sem_post(&sem);
    }
}

void *consumer(void *arg) {
    while (1) {
        sleep(1);
        sem_wait(&sem);
        buffer--;
        printf("[Consumer] buffer value: %d\n", buffer);
        sem_post(&sem);
    }
}

int main() {
    pthread_t pid, cid;
    sem_init(&sem, 0, 1);
    pthread_create(&pid, NULL, producer, NULL);
    pthread_create(&cid, NULL, consumer, NULL);
    pthread_join(pid, NULL);
    pthread_join(cid, NULL);
    sem_destroy(&sem);
    return 0;
}
解题思路

该程序是一个经典的生产者消费者模型,使用了信号量作为进程同步和通信的机制。

在主函数中,我们创建了两个子线程,一个生产者线程 producer 和一个消费者线程 consumer,同时创建了一个信号量 sem 并初始化为 1。

在子线程中,我们使用了 sem_wait()sem_post() 两个信号量相关的函数来进行进程同步和通信。其中,sem_wait() 函数会将信号量的值减一,如果当前信号量的值小于零,该函数会阻塞线程并等待信号量释放。而 sem_post() 函数则会将信号量的值加一,并唤醒阻塞在该信号量上的线程。

在生产者线程中,我们使用 sem_wait() 函数等待信号量,并在临界区中将 buffer 的值加一并进行输出。在消费者线程中,我们也使用sem_wait()函数等待信号量,并在临界区中将buffer的值减一并进行输出。

最终,当我们将两个线程 join 回主函数时,我们销毁了信号量并结束了程序运行。

程序输出

根据生产者消费者模型的特点,在阻塞条件下,生产者和消费者会依次交替运行,且生产者和消费者不能同时对 buffer 进行修改操作。因此,我们可以预测程序的输出结果应该是:

[Producer] buffer value: 1
[Consumer] buffer value: 0
[Producer] buffer value: 1
[Consumer] buffer value: 0
[Producer] buffer value: 1
[Consumer] buffer value: 0
...
代码实现
```c
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>

sem_t sem;
int buffer = 0;

void *producer(void *arg) {
    while (1) {
        sleep(1);
        sem_wait(&sem);
        buffer++;
        printf("[Producer] buffer value: %d\n", buffer);
        sem_post(&sem);
    }
}

void *consumer(void *arg) {
    while (1) {
        sleep(1);
        sem_wait(&sem);
        buffer--;
        printf("[Consumer] buffer value: %d\n", buffer);
        sem_post(&sem);
    }
}

int main() {
    pthread_t pid, cid;
    sem_init(&sem, 0, 1);
    pthread_create(&pid, NULL, producer, NULL);
    pthread_create(&cid, NULL, consumer, NULL);
    pthread_join(pid, NULL);
    pthread_join(cid, NULL);
    sem_destroy(&sem);
    return 0;
}