孙某某为什莫666666666

问题遇到的现象和发生背景 牛
操作环境、软件版本等信息 牛
尝试过的解决方法 牛
我想要达到的结果牛

你为什莫这莫你牛

你牛

【相关推荐】



  • 你可以看下这个问题的回答https://ask.csdn.net/questions/7625159
  • 这篇博客也不错, 你可以看下当一个软件缺陷走完了它的生命周期是不是就意味着这个缺陷已经被修复了?
  • 您还可以看一下 吴刚老师的【吴刚】电商网站详情页设计初级入门标准视频教程课程中的 23-文案屏的文字排版布局制作小节, 巩固相关知识点
  • 除此之外, 这篇博客: 湖南大学操作系统导论课程作业中的 30.9 现在将消费者数量更改为两个。 为生产者消费者配置睡眠字符串,从而使代码运行出现问题。 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:

    ./main-one-cv-while -p 1 -c 2 -m 1 -C 0,0,0,3:0,0,0,3 -P 1 -l 2 -v -t
    即使不配置睡眠字符串,也可能出现如下情况:

    生产者生产后,缓冲区满了,唤醒了两个正在睡眠的消费者中的一个,然后进入睡眠(Mutex_lock)
    消费者消费后,唤醒另一个消费者,进入睡眠(Mutex_lock),
    新的消费者线程被唤醒,发现缓冲区为空,进入睡眠(Cond_wait),此时三个线程都进入睡眠
    无法配置睡眠字符串,使得代码运行必定出现问题,取决与操作系统的线程调度

    我尝试通过休眠字符干预程序的线程调度,想法是这样的,模拟课本引发问题的顺序:
    在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述
    生产者线程先运行,在p0处强制睡眠,让消费者先执行。让两个消费者都一直运行到c3处后强行睡眠,使得生产者可以在p5唤醒一个消费者后继续执行,而不是切换到消费者线程。生产者一直运行直到运行到第二次p3。然后c1运行,消费,消费完后唤醒c2,c2起来消费,发现为空。睡眠。这时候3个对象都进入睡眠。

    但在实践中发现是这个样子的:
    在这里插入图片描述
    消费者运行到c2后就不再运行了,无论怎么配置睡眠因子,都不能使得一个消费者一口气执行完c0~c3。无论如何都会在c2处穿插运行一个生产者。
    而且有一点非常奇怪就是红色方框下面那个c3,它执行完后立刻就变c4了。而代码逻辑是:
    在这里插入图片描述
    c3无论如何都得经过一个c2才能到c4。
    所以得到两个问题使得我怀疑程序的正确性:

    1. 无法通过睡眠因子控制调度。(理论上是可以的,只需要在不希望某个线程执行的时候加个睡眠因子使他无法被调度而被迫执行其他线程)
    2. 加入睡眠因子后,程序的逻辑竟然不合理了,c3竟然可以不经过c2直接执行c4。

    但我认为我的配置是正确的,也就是:

    ./main-one-cv-while -p 1 -c 2 -m 1 -C 0,0,0,3:0,0,0,3 -P 1 -l 2 -v -t
    只是程序有问题(我有较大把握认为程序有问题),导致我运行不出想要的结果

    后来经过讨论,发现课本的方案确实不好实现,跳出课本的限制。想另一种方案。

    经过与同学讨论,得到了一个可以让所有线程都休眠的配置方案:

    ./main-one-cv-while -p 1 -c 2 -m 1 -P 0,0,0,0,0,0,1 -l 2 -v -t
    在这里插入图片描述
    最后会卡住,达到效果。其原理和课本的不同。

    课本是让生产者和消费者1睡,消费者2起导致异常。具体顺序为:生产者睡->消费者1"消费完”"睡之前"唤醒消费者2(按照逻辑它应该唤醒生产者才不会错)。这里对调度干预非常严格,严格在"消费完”,“睡之前”这个两个动作必须是原子操作。可以看到:
    在这里插入图片描述
    c6(消费完)之后要马上执行c1c2c3(睡之前),这个要求是没办法确定的。这个程序的调度算法并没有让c6(消费完)执行后马上执行c1(睡之前)的机制。因此课本的方案无法复现。

    同学这个方案能成功的原理是让生产者和消费者1死,消费者1死之前唤醒消费者2。此时只有消费者2,但消费者2的动作是:睡。它一旦睡了,由于生产者和消费者已经死了,不会有人再叫醒2了,2会一直睡下去。
    在这里插入图片描述
    这里,第4行,生产者生产完一个结束位后线程死亡。消费者1消费完这个结束位后线程死亡,死之前还叫醒了消费者2。


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^