这是一个生产者消费者问题的解决方案,使用了信号量和互斥锁来实现线程同步和互斥。代码中定义了一个大小为 10 的缓冲区,生产者线程每次向缓冲区中插入一个随机数,消费者线程每次从缓冲区中取出一个数。当缓冲区满时,生产者线程需要等待,当缓冲区为空时,消费者线程需要等待。具体实现中,使用了 Windows API 中的 CreateMutex、CreateSemaphore、WaitForSingleObject、ReleaseMutex、ReleaseSemaphore 等函数。最后,程序运行时间设为了 400000 毫秒,即约为 6 分钟。

#include<iostream>
#include<cstdlib>
#include<ctime>
#include<windows.h>
using namespace std;

const int BUFFER_SIZE=10;
int buffer[BUFFER_SIZE];
int front,rear;
bool full;
HANDLE Mutex;
HANDLE Full;
HANDLE Empty;

void showBuffer(){
    cout'buffer: ';
    if(front!=rear||full){
        int i=front;
        do{
            cout<<buffer[i]' ';
            i=(i+1)%BUFFER_SIZE;
        }while(i!=rear);
    }else
        cout'empty';
    cout'\n*******************************'\n<<endl;
}

int insert_item(int item){
    int condition = -1;
    WaitForSingleObject(Empty,INFINITE);
    WaitForSingleObject(Mutex,INFINITE);

    if(!full){
        buffer[rear]= item;
        rear=(rear+1)%BUFFER_SIZE;
        if(rear==front)full=true;
        condition=0;
        cout'producer produced '<<item<<endl;
        showBuffer();
    }

    ReleaseMutex(Mutex);
    ReleaseSemaphore(Full,1,NULL);
    return condition;
}

int remove_item(int item){
    int condition = -1;
    WaitForSingleObject(Full,INFINITE); //获得信号量的一个占有权 
    WaitForSingleObject(Mutex,INFINITE);//加锁 
    if(front!=rear||full){
        item=buffer[front];
        front=(front+1)%BUFFER_SIZE;
        full=false;
        condition=0;

        cout'consumer comsumed '<<item<<endl;
        showBuffer();
    }
    ReleaseMutex(Mutex); //解锁 
    ReleaseSemaphore(Empty,1,NULL); // 释放信号量的一个占有权 
    return condition;
}

DWORD WINAPI producer(void *param){
    srand((unsigned)time(0));

    for(int i=0;;++i){
        Sleep((rand()%50)+2000);
        insert_item(rand()%BUFFER_SIZE);
    }
};
DWORD WINAPI consumer(void *param){
    srand((unsigned)time(0));
    for(int j=0;;j++){
        Sleep((rand()%100)+2500);
        remove_item(rand()%BUFFER_SIZE);
    }
};

int main(int argc, char *argv[]){
    front=0;
    rear=0;
    full=false;

    Mutex=CreateMutex(NULL,FALSE,NULL);
    Full=CreateSemaphore(NULL,0,5,NULL); //创建一个信号量 
    Empty=CreateSemaphore(NULL,5,5,NULL);
    CreateThread(NULL,0,producer,NULL,0,NULL);
    CreateThread(NULL,0,consumer,NULL,0,NULL);

    Sleep(400000);
    return 0;
}

代码解释:

  • 头文件包含
    • iostream:用于标准输入输出
    • cstdlib:用于随机数生成
    • ctime:用于获取当前时间
    • windows.h:用于使用 Windows API
  • 全局变量定义
    • BUFFER_SIZE:缓冲区大小,定义为 10
    • buffer:用于存储数据的缓冲区
    • front:缓冲区前端指针
    • rear:缓冲区后端指针
    • full:指示缓冲区是否已满
    • Mutex:互斥锁,用于保证同一时刻只有一个线程访问缓冲区
    • Full:信号量,用于控制生产者线程,当缓冲区满时,生产者线程需要等待该信号量
    • Empty:信号量,用于控制消费者线程,当缓冲区为空时,消费者线程需要等待该信号量
  • 函数定义
    • showBuffer():用于打印缓冲区内容
    • insert_item():生产者线程的插入操作,将随机数插入缓冲区,并处理缓冲区满的情况
    • remove_item():消费者线程的删除操作,从缓冲区中取出一个数,并处理缓冲区空的情况
    • producer():生产者线程,不断生成随机数并插入缓冲区
    • consumer():消费者线程,不断从缓冲区中取出数据
  • 主函数
    • 初始化全局变量
    • 创建互斥锁、信号量
    • 创建生产者线程和消费者线程
    • 等待 400000 毫秒(约 6 分钟)
    • 返回 0

代码使用 CreateMutex 创建互斥锁,CreateSemaphore 创建信号量。WaitForSingleObject 用于等待互斥锁或信号量,ReleaseMutex 用于释放互斥锁,ReleaseSemaphore 用于释放信号量。

代码的核心思想是使用信号量来控制生产者和消费者线程的执行速度,使用互斥锁来保证同一时刻只有一个线程访问缓冲区,从而避免数据竞争。

希望这段代码解释对您有所帮助!如果您还有其他问题,请随时提问。

生产者消费者问题:使用信号量和互斥锁的 C++ 实现

原文地址: https://www.cveoy.top/t/topic/ocyN 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录