V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
mstar
V2EX  ›  问与答

关于 csapp 的一道 生产者-消费者 练习题的困惑

  •  
  •   mstar · 2016-06-13 12:12:48 +08:00 · 2730 次点击
    这是一个创建于 3067 天前的主题,其中的信息可能已经有所发展或是发生改变。

    最近在读 csapp ,第 12 章的练习题 12.9 , A 场景,答案说是生产者和消费者会并发访问缓冲区,所以必须要有互斥锁。我没有太理解,我觉得虽然它们会并发访问同一个 buf ,但并不会并发访问同一个 item ,因为生产者和消费者最接近的时候也隔着一个 item ,所以我觉得这种场景下互斥锁不是必须的。大家能帮我下?(第一次发帖,如果有不对的请轻拍:))

    第 1 条附言  ·  2016-06-13 13:56:12 +08:00

    以下是sbuf_t

    typedef struct {
    	int *buf; /* Buffer array */
    	int n; /* Maximum number of slots */
    	int front; /* buf[(front+1)%n] is first item */
    	int rear; /* buf[rear%n] is last item */
    	sem_t mutex; /* Protects accesses to buf */
    	sem_t slots; /* Counts available slots */
    	sem_t items; /* Counts available items */
    } sbuf_t;
    

    以下是SBUF函数实现

    #include "csapp.h"
    #include "sbuf.h"
    
    /* Create an empty, bounded, shared FIFO buffer with n slots */
    void sbuf_init(sbuf_t *sp, int n)
    {
    	sp->buf = Calloc(n, sizeof(int));
    	sp->n = n; /* Buffer holds max of n items */
    	sp->front = sp->rear = 0; /* Empty buffer iff front == rear */
    	Sem_init(&sp->mutex, 0, 1); /* Binary semaphore for locking */
    	Sem_init(&sp->slots, 0, n); /* Initially, buf has n empty slots */
    	Sem_init(&sp->items, 0, 0); /* Initially, buf has zero data items */
    }
    
    /* Clean up buffer sp */
    void sbuf_deinit(sbuf_t *sp)
    {
    	Free(sp->buf);
    }
    
    /* Insert item onto the rear of shared buffer sp */
    void sbuf_insert(sbuf_t *sp, int item)
    {
    	P(&sp->slots); /* Wait for available slot */
    	P(&sp->mutex); /* Lock the buffer */
    	sp->buf[(++sp->rear)%(sp->n)] = item; /* Insert the item */
    	V(&sp->mutex); /* Unlock the buffer */
    	V(&sp->items); /* Announce available item */
    }
    
    /* Remove and return the first item from buffer sp */
    int sbuf_remove(sbuf_t *sp)
    {
    	int item;
    	P(&sp->items); /* Wait for available item */
    	P(&sp->mutex); /* Lock the buffer */
    	item = sp->buf[(++sp->front)%(sp->n)]; /* Remove the item */
    	V(&sp->mutex); /* Unlock the buffer */
    	V(&sp->slots); /* Announce available slot */
    	return item;
    }
    

    sbuf_init()函数初始化一次,然后生产者调用sbuf_insert(),消费者调用sbuf_remove()。

    第 2 条附言  ·  2016-06-13 13:57:02 +08:00
    以下是题目

    Let p denote the number of producers, c the number of consumers, and n the
    buffer size in units of items. For each of the following scenarios, indicate whether
    the mutex semaphore in sbuf_insert and sbuf_remove is necessary or not.
    A. p = 1, c = 1, n > 1
    B. p = 1, c = 1, n = 1
    C. p > 1, c > 1, n = 1
    1 条回复    2020-05-10 18:28:02 +08:00
    iEverX
        1
    iEverX  
       2020-05-10 18:28:02 +08:00
    同样的疑问,但是网上搜不到。同认为 A 可以不要 mutex
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5923 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 01:58 · PVG 09:58 · LAX 17:58 · JFK 20:58
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.