zoukankan      html  css  js  c++  java
  • 生产者消费者问题Semaphore

    /* productandconsumer. cpp */
    #include
    <windows.h>
    #include
    <stdio.h>
    #include
    <stdlib.h>

    typedef HANDLE Semaphore;
    //信号量的Windows 原型

    #define P(S) WaitForSingleObject (S, INFINITE) //定义P操作
    #define V(S) ReleaseSemaphore (S, 1, NULL) //定义V操作

    #define CONSUMER_NUM 10 /* 消费者个数*/
    #define PRODUCER_NUM 10 /*生产者个数*/
    #define BUFFER_NUM 5 /* 缓冲区个数*/

    char *fruit[10] = {"桔子", "苹果", "香蕉", "菠萝", "草莓", "荔枝", "樱桃", "葡萄", "桃子", "鸭梨"};

    struct Buffer
    {
    int buf[BUFFER_NUM]; //缓冲区
    int out, in; //两个指针
    }pub_buf;

    Semaphore empty, full, mutex;

    //消费者线程
    DWORD WINAPI Consumer(LPVOID para)
    {
    //i 表示第i 个消费者
    int i = *(int *)para;
    int ptr; //待消费的内容的指针
    printf("消费者%03d: 我来啦...\n", i);
    Sleep(
    300);
    while(1)
    {
    printf(
    "消费者%03d: 我要吃...\n", i);
    P(full);
    //等待产品
    P(mutex); //有产品, 先锁住缓冲区pub_buf
    ptr = pub_buf.out; //记录消费的物品
    pub_buf.out = (pub_buf.out + 1) % BUFFER_NUM; //再移动缓冲区指针
    V(mutex); //让其他消费者或生产者使用pub_buf
    printf("消费者%03d: 开始吃 buf[%d]=%s\n", i, ptr, fruit[pub_buf.buf[ptr]]);
    Sleep (
    1000 * rand() % 10 + 110);
    printf(
    "消费者%03d: 吃完了 buf[%d]=%s\n", i, ptr, fruit[pub_buf.buf[ptr]]);
    V(empty);
    //消费完毕, 并释放一个缓冲
    }
    return 0;
    }
    //生产者线程
    DWORD WINAPI Producer (LPVOID para)
    {
    int i = *(int *)para - CONSUMER_NUM;
    int ptr; int data; //产品
    printf("生产者%03d:我来啦\n", i);
    Sleep(
    300);
    while (1)
    {
    printf(
    "生产者%03d: 我生产.\n", i);
    Sleep(
    1000 * rand () %10 + 110);
    data
    = rand() %10;
    printf(
    "生产者%03d: 送来一个水果:%s\n", i, fruit[data]);
    P(empty);
    P(mutex);
    //有地方, 先锁住缓冲区pub_buf
    ptr = pub_buf.in; //记录消费的物品
    pub_buf.in = (pub_buf.in + 1) % BUFFER_NUM;
    V(mutex);
    //让其他消费者或生产者使用pub_buf
    printf("生产者%03d: 开始搁置 buf[%d]=%s\n", i, ptr, fruit[data]);
    pub_buf.buf[ptr]
    = data;
    Sleep(
    1000/ 2 * rand () %10 + 110);
    printf(
    "生产者%03d: 搁置完成 buf[%d]=%s\n", i, ptr, fruit[pub_buf.buf[ptr]]);
    V(full);
    //放好了完毕, 释放一个产品
    }
    return 0;
    }

    int main ( )
    {
    //线程计数, 前面为消费者线程, 后面为生产者线程
    HANDLE hThreadGroup[CONSUMER_NUM + PRODUCER_NUM];
    DWORD tid; size_t i
    = 0;
    //初始化信号量
    mutex = CreateSemaphore(NULL, 1, BUFFER_NUM, (LPCWSTR)("mutex"));
    empty
    = CreateSemaphore(NULL, BUFFER_NUM, BUFFER_NUM, (LPCWSTR)("empty"));
    full
    = CreateSemaphore(NULL, 0, BUFFER_NUM, (LPCWSTR)("full"));
    if (!empty || !full || !mutex)
    {
    printf(
    "Create Semaphone Error!\n");
    return - 1;
    }
    size_t uTotalThreads
    = CONSUMER_NUM + PRODUCER_NUM;
    for (i = 0; i < CONSUMER_NUM; i++)
    {
    hThreadGroup[i]
    = CreateThread(NULL, 0, Consumer, &i, 0, &tid);
    if (hThreadGroup[i] )
    WaitForSingleObject(hThreadGroup[i],
    10);
    }
    for (; i < uTotalThreads; i++)
    {
    hThreadGroup[i]
    = CreateThread(NULL, 0, Producer, &i, 0, &tid);
    if (hThreadGroup[i])
    WaitForSingleObject(hThreadGroup[i],
    10);
    }
    //生产者和消费者的执行
    WaitForMultipleObjects(uTotalThreads, hThreadGroup, false, INFINITE);
    }
  • 相关阅读:
    jQuery操作Table学习总结[转]
    SQL语句中的单引号处理以及模糊查询
    正则表达式实现将html文本转换为纯文本格式(将html字符串转换为纯文本方法)
    ASP.NET中使用UpdatePanel实现局部异步刷新方法和攻略(转)
    Response.Redirect在新窗口打开(转载)
    position属性absolute与relative 的区别
    下载文件
    gridveiw的使用
    MarkDown和流程图诠释你的代码
    git使用笔记
  • 原文地址:https://www.cnblogs.com/steady/p/2003168.html
Copyright © 2011-2022 走看看