操作系统实验 C++实现生产者-消费者问题

实验目的

1、进一步加深理解进程同步的概念

2、加深对进程通信的理解

3、了解Linux下共享内存的使用方法

实验内容

1、按照下面要求,写两个c程序,分别是生产者producer.c以及customer.c

2、一组生产者和一组消费者进程共享一块环形缓冲区

使用共享内存+信号量实现生产者-消费者

1、生产者进程:在第0个缓冲区写入a,第1个写入b,……,第9个写入j,并在屏幕上打印:“Producer-pid:write Y”,其中Y为写入字符,pid为生产者进程的进程ID;

2、消费者进程:依次从缓冲区中读出写入字符,读出后,将该缓冲区置为X,并在屏幕上打印:“Customer:read Y”,其中Y为读出字符,pid为消费者进程的进程ID;

基本思路

  • 定义一个数据结构:

typedef struct{         

        int write;//当前要写的缓冲区         i

        nt read;//当前要读的缓冲区         

        char buf[10];//10个缓冲区

}shared_buf;

  • 创建一个大小为sizeof(shared_buf)的共享内存
  • Producer:在buf[write]写字符‘a’+ write,然后write = (++write)% 10;
  • Customer:读buf[read]中字符,并置buf[read] = ‘X’,然后read = (++read)% 10;
  • 使用信号量:full、empty、mutex来进行同步及互斥

参考:共享内存

Linux POSIX共享内存

Linux System V共享内存

实验代码

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <process.h>

// 定义共享数据结构
typedef struct {
    int write;
    int read;
    char buf[10];
} shared_buf;

// 信号量句柄
HANDLE empty_semaphore;
HANDLE full_semaphore;
HANDLE mutex_semaphore;

// 共享内存句柄
HANDLE shared_memory_handle;
shared_buf* shared_memory_ptr;

// 生产者函数
unsigned __stdcall producer(void* arg) {
    int pid = _getpid();
    for (int i = 0; i < 20; i++) {
        // 等待有空缓冲区
        WaitForSingleObject(empty_semaphore, INFINITE);
        // 互斥访问共享内存
        WaitForSingleObject(mutex_semaphore, INFINITE);

        char ch = 'a' + i;
        shared_memory_ptr->buf[shared_memory_ptr->write] = ch;
        printf("Producer - %d: write %c\n", pid, ch);
        shared_memory_ptr->write = (shared_memory_ptr->write + 1) % 10;

        ReleaseSemaphore(mutex_semaphore, 1, NULL);
        ReleaseSemaphore(full_semaphore, 1, NULL);
    }
    return 0;
}

// 消费者函数
unsigned __stdcall consumer(void* arg) {
    int pid = _getpid();
    for (int i = 0; i < 20; i++) {
        // 等待有满缓冲区
        WaitForSingleObject(full_semaphore, INFINITE);
        // 互斥访问共享内存
        WaitForSingleObject(mutex_semaphore, INFINITE);

        char ch = shared_memory_ptr->buf[shared_memory_ptr->read];
        shared_memory_ptr->buf[shared_memory_ptr->read] = 'X';
        printf("Consumer - %d: read %c\n", pid, ch);
        shared_memory_ptr->read = (shared_memory_ptr->read + 1) % 10;

        ReleaseSemaphore(mutex_semaphore, 1, NULL);
        ReleaseSemaphore(empty_semaphore, 1, NULL);
    }
    return 0;
}

int main() {
    // 创建信号量
    empty_semaphore = CreateSemaphore(NULL, 10, 10, NULL);
    full_semaphore = CreateSemaphore(NULL, 0, 10, NULL);
    mutex_semaphore = CreateSemaphore(NULL, 1, 1, NULL);

    // 创建共享内存
    shared_memory_handle = CreateFileMapping(
        INVALID_HANDLE_VALUE,
        NULL,
        PAGE_READWRITE,
        0,
        sizeof(shared_buf),
        "SharedMemory"
    );
    if (shared_memory_handle == NULL) {
        perror("CreateFileMapping");
        return 1;
    }
    shared_memory_ptr = (shared_buf*)MapViewOfFile(
        shared_memory_handle,
        FILE_MAP_ALL_ACCESS,
        0,
        0,
        sizeof(shared_buf)
    );
    if (shared_memory_ptr == NULL) {
        perror("MapViewOfFile");
        CloseHandle(shared_memory_handle);
        return 1;
    }

    // 初始化共享内存
    shared_memory_ptr->write = 0;
    shared_memory_ptr->read = 0;
    for (int i = 0; i < 20; i++) {
        shared_memory_ptr->buf[i] = 'X';
    }

    // 创建生产者和消费者线程
    unsigned thread_id_producer;
    unsigned thread_id_consumer;
    HANDLE producer_thread = (HANDLE)_beginthreadex(NULL, 0, producer, NULL, 0, &thread_id_producer);
    HANDLE consumer_thread = (HANDLE)_beginthreadex(NULL, 0, consumer, NULL, 0, &thread_id_consumer);

    // 等待线程结束
    WaitForSingleObject(producer_thread, INFINITE);
    WaitForSingleObject(consumer_thread, INFINITE);

    // 清理资源
    UnmapViewOfFile(shared_memory_ptr);
    CloseHandle(shared_memory_handle);
    CloseHandle(empty_semaphore);
    CloseHandle(full_semaphore);
    CloseHandle(mutex_semaphore);
    CloseHandle(producer_thread);
    CloseHandle(consumer_thread);

    return 0;
}

实验结果

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值