Concurrency 此生产者-消费者代码何时会发生死锁

Concurrency 此生产者-消费者代码何时会发生死锁,concurrency,operating-system,synchronization,deadlock,producer-consumer,Concurrency,Operating System,Synchronization,Deadlock,Producer Consumer,我正在阅读关于生产者消费者问题的文章,其中给出了以下代码: +----------------------------------------------------+-------------------------------------------------------+ | Producer | Consumer

我正在阅读关于生产者消费者问题的文章,其中给出了以下代码:

+----------------------------------------------------+-------------------------------------------------------+
|               Producer                             |             Consumer                                  |
+------------------------------------------------------------------------------------------------------------+
| 1  int n;                                          | 1  void consumer()                                    |
| 2  binary_semaphore mx = 1, delay = 0;             | 2  {  semWaitB(delay);  //wait till first data item   |
| 3  void producer()                                 | 3                       //is produced                 |
| 4  {                                               | 4     while (true)                                    |
| 5     while (true)                                 | 5     {                                               |
| 6     {                                            | 6        semWaitB(mx); //continue if producer is not  |
| 7        produce();                                | 7                      //producing                    |
| 8        semWaitB(mx);  //continue if consumer     | 8        take();                                      |
| 9                       //is not consuming         | 9        n--;                                         |
| 10        append();                                | 10        semSignalB(mx);//signal done with consuming |
| 11        n++;                                     | 11        consume();                                  |
| 12        if (n==1) semSignalB(delay);  //unblocks | 12        if (n==0) semWaitB(delay);  //block self if |
| 13                                      //consumer | 13                                    //no data item  |
| 14        semSignalB(mx);  //signal done with      | 14     }                                              |
| 15                         //producing             | 15  }                                                 |
| 16     }                                           | 16  void main()                                       |
| 17  }                                              | 17  {  n = 0;                                         |
|                                                    | 18     parbegin (producer, consumer);                 |
|                                                    | 19  }                                                 |
+----------------------------------------------------+-------------------------------------------------------+
然后说明(参考下表中的行号):

如果消费者排气缓冲区将n设置为0(第8行),则在消费者检查n并等待第14行之前,生产者已将其增加到1(表的第11行)。第14行应该阻止使用者,因为缓冲区已用尽,但它并没有阻止,因为生产者同时增加了n。最坏的情况是,消费者可以立即再次运行以消耗不存在的项目,从而将n减少到-1(第20行)

然后它说:

我们不能将条件语句移到临界段内,因为这可能导致死锁(例如,在上表第8行之后)

它继续给出不同的解决方案

但我无法理解这将如何导致僵局。考虑以下修改后的消费者代码:

1  void consumer()
2  {  semWaitB(delay);  //wait till first data item
3                       //is produced
4     while (true) 
5     {
6        semWaitB(mx); //continue if producer is not 
7                      //producing
8        take();
9        n--;
10        if (n==0) semWaitB(delay);  //block self if
11                                    //no data item
12        semSignalB(mx);//signal done with consuming
13        consume();
14     }
15  }
16  void main()
17  {  n = 0;
18     parbegin (producer, consumer);
19  }
我得出了以下结论:


如您所见,在最后,mx、n和delay的值被重置为启动前的值。那么这怎么会导致僵局呢?(事实上,我觉得这可能是一个精确的解决方案。)

这肯定会导致僵局。考虑操作顺序:

生产商成功生产1件商品。这将产生以下sempaphores值:

mx = 1 and delay = 1
现在消费者执行其代码并到达第10行

if (n==0) semWaitB(delay);
因为消费者的第2行将延迟设置为
0

semWaitB(delay);
第10行将阻塞消费者,此时我们有
mx=0
,因为消费者
semWaitB(mx)的第6行


由于第8行<代码>semWaitB(mx),消费者已被封锁,生产者将被封锁as
mx=0
这是一个死锁

它肯定会导致死锁。考虑操作顺序:

生产商成功生产1件商品。这将产生以下sempaphores值:

mx = 1 and delay = 1
现在消费者执行其代码并到达第10行

if (n==0) semWaitB(delay);
因为消费者的第2行将延迟设置为
0

semWaitB(delay);
第10行将阻塞消费者,此时我们有
mx=0
,因为消费者
semWaitB(mx)的第6行


由于第8行<代码>semWaitB(mx),消费者已被封锁,生产者将被封锁as
mx=0
这是一个死锁

请随时查询。请随时查询。