C++ C++;代码编译但死亡问题(有一行(队列)、一个缓冲区,如果不是空的问题)

C++ C++;代码编译但死亡问题(有一行(队列)、一个缓冲区,如果不是空的问题),c++,multithreading,boost,queue,C++,Multithreading,Boost,Queue,所以我有一节课。h文件中包含一些变量,如: struct AudioSample { const unsigned char * buffer; int len; }; //... const unsigned char * VideoFrameBuffer; int VideoFrameLen; std::queue<AudioSample> AudioSamples; bool sample

所以我有一节课。h文件中包含一些变量,如:

  struct AudioSample
  { 
    const unsigned char * buffer;
      int len;
  };
        //...
      const unsigned char * VideoFrameBuffer;
      int VideoFrameLen;


  std::queue<AudioSample> AudioSamples;


  bool sampleSendingFinished;
  bool frameSendingFinished;
      //...
偶尔有些函数会调用AddFrameToQueue和AddSampleToQueue。UrlWriteData生活在单独的线程中。 我的应用程序可以编译。但我的问题是——当我运行它时,它会在网上死掉:

        else if(!AudioSamples.empty())
        {
            struct AudioSample newAudioSample = AudioSamples.front();

为什么它会死,以及如何使它不会死?

我相信你是一个新手,你从某个地方剪切并复制了这段代码,从中剥离了所有不必要的东西,直到编译完成。现在你很好奇为什么这不起作用。我说得对吗

好吧,只是一个问题的初步清单,没有太多的细节:

  • 当从不同线程访问相同数据时,多线程应用程序通常需要正弦同步机制。例如关键部分、互斥体等,或至少联锁(无锁)操作和/或内存屏障。我在你的代码中没有看到类似的东西
  • 在您的特定情况下,
    AudioSamples
    是一个由多个线程操作的复杂对象。必须由关键部分(或类似部分)对其进行保护
  • 设置/查询
    VideoFrameBuffer
    VideoFrameLen
    的方法相同
  • 在您获取下一个音频样本后,您应该将其从队列中取出(调用
    pop\u front
  • “音频样本”和“视频帧”数据成员都只包含指向实际数据的指针。从您的设计中(如果有)不清楚谁拥有分配内存的“所有权”。简单地说,谁应该释放分配的内存

  • 我相信你是个新手,你从某个地方剪切并复制了这段代码,从中剥离了所有不必要的东西,直到编译完成。现在你很好奇为什么这不起作用。我说得对吗

    好吧,只是一个问题的初步清单,没有太多的细节:

  • 当从不同线程访问相同数据时,多线程应用程序通常需要正弦同步机制。例如关键部分、互斥体等,或至少联锁(无锁)操作和/或内存屏障。我在你的代码中没有看到类似的东西
  • 在您的特定情况下,
    AudioSamples
    是一个由多个线程操作的复杂对象。必须由关键部分(或类似部分)对其进行保护
  • 设置/查询
    VideoFrameBuffer
    VideoFrameLen
    的方法相同
  • 在您获取下一个音频样本后,您应该将其从队列中取出(调用
    pop\u front
  • “音频样本”和“视频帧”数据成员都只包含指向实际数据的指针。从您的设计中(如果有)不清楚谁拥有分配内存的“所有权”。简单地说,谁应该释放分配的内存

  • 你追踪到哪条线路出故障了吗?它在哪里死去?如何管理buf的内存?你的代码是同步的吗?(顺便说一句,FFmpeg库似乎已经打过补丁,url_write现在是const正确的。如果不是这样,最好使用const_cast,而不是C cast,尽管有人会说这是一种风格)

    作为对代码的一般性评论:

    • 轮询有其优点(此时您可以处理多个队列项目),但我不确定这是否是您想要的。您可能希望使用某种阻塞/等待系统。如果这是Windows,则由WaitForSingleObject和类似类型的调用完成。在UNIX上,您可以pthread_cond_wait或选择导致阻塞。当线程有东西要处理时,它就会被唤醒

    您追踪到哪条线路出现故障了吗?它在哪里死去?如何管理buf的内存?你的代码是同步的吗?(顺便说一句,FFmpeg库似乎已经打过补丁,url_write现在是const正确的。如果不是这样,最好使用const_cast,而不是C cast,尽管有人会说这是一种风格)

    作为对代码的一般性评论:

    • 轮询有其优点(此时您可以处理多个队列项目),但我不确定这是否是您想要的。您可能希望使用某种阻塞/等待系统。如果这是Windows,则由WaitForSingleObject和类似类型的调用完成。在UNIX上,您可以pthread_cond_wait或选择导致阻塞。当线程有东西要处理时,它就会被唤醒

      • 有一个线程安全的生产者-消费者队列,使用即将成为标准的线程机制。这将是一个很好的介绍线程的概念,你必须了解使这个设计工作


        生产者是添加到队列中的函数,消费者是读取和(通常)处理队列条目的函数-
        UrlWriteData
        ,此处。

        有一个线程安全的生产者-消费者队列,使用即将成为标准的线程机制。这将是一个很好的介绍线程的概念,你必须了解使这个设计工作


        生产者是添加到队列中的函数,消费者是读取和(通常)处理队列条目的函数-
        UrlWriteData
        ,此处。

        std::queue没有pop\u front just push()和pop()。不过,您需要添加自己的线程安全性。std::queue没有pop_front,只需push()和pop()。不过,您需要添加自己的线程安全性。@Kabumbus-不需要在封装的
        std::queue
        -
        try\u pop
        wait\u and\u pop
        上直接调用
        front()
        。正如您所看到的,他们每次都使用
        front()
        来提取对所需
        数据的引用,这是
        并发队列的最后一个代码
        @Kabumbus-没有必要使用
                else if(!AudioSamples.empty())
                {
                    struct AudioSample newAudioSample = AudioSamples.front();