使用condition_variable

时间:2017-11-07 22:07:53

标签: c++ multithreading concurrency shared-memory producer-consumer

我现在必须深入了解C ++ 11的并发性,并且我有一个非常困难的时间让一个基本的生产者/消费者使用Boost.Interprocess使用{ {3}}。我已经尝试了很多不同的东西,但是我不能让两个简单的程序(1x生产者,1x消费者)以可靠的方式工作,因为它们会遇到死锁。

我有以下要求:

  1. 无论流程执行顺序如何,该示例均可正常工作。如果首先启动consumerproducer应该会产生功能差异。

    注意:因此我在两个进程中使用boost::interprocess::open_or_create(也许会导致问题)。

  2. 如果消费者通知,生产者应构建共享内存对象(在本例中为int)。
  3. 如果生产者通知,消费者应阅读共享内存对象,打印读取数据并销毁共享内存对象。
  4. 每个流程都不应“轮询”,而是阻止/等待直到允许它完成工作(津贴来自其他流程)。
  5. 这是我当前的C ++代码,它会导致死锁,甚至不会产生和/或消耗一个对象。在看了很长时间的代码后,我无法看到森林中的树木。

    producer.cpp

    // Standard Library
    #include <iostream>
    #include <thread>
    
    // Boost.Interprocess
    #include <boost/interprocess/managed_shared_memory.hpp>
    #include <boost/interprocess/sync/named_condition.hpp>
    #include <boost/interprocess/sync/named_mutex.hpp>
    
    int main() {
      std::cout << "Started Producer" << std::endl;
    
      try {
        std::cout << "Producer: Open/Create shared memory segment" << std::endl;
        boost::interprocess::managed_shared_memory managed_shm{
            boost::interprocess::open_or_create, "SharedMemory_Segment", 1024};
        std::cout << "Producer: Open/Create mutex" << std::endl;
        boost::interprocess::named_mutex mutex{boost::interprocess::open_or_create,
                                               "SharedMemory_Mutex"};
        std::cout << "Producer: Open/Create condition" << std::endl;
        boost::interprocess::named_condition condition_read{
            boost::interprocess::open_or_create, "SharedMemory_ConditionRead"};
        boost::interprocess::named_condition condition_write{
            boost::interprocess::open_or_create, "SharedMemory_ConditionWrite"};
    
        std::cout << "Producer: Start work" << std::endl;
        for (int i = 0; i < 10; ++i) {
          std::cout << "Producer: Try to get the lock for the shared mutex "
                       "(potential blocking)"
                    << std::endl;
          boost::interprocess::scoped_lock<boost::interprocess::named_mutex> lock{
              mutex};
    
          std::cout << "Producer: Wait for Consumer" << std::endl;
          condition_read.wait(lock);
    
          std::cout << "Producer: Construct data" << std::endl;
          managed_shm.construct<int>("SharedMemory_Data")(i);
    
          std::cout << "Producer: Unlock the mutex" << std::endl;
          lock.unlock();
    
          std::cout << "Producer: Notify Consumer" << std::endl;
          condition_write.notify_one();
        }
      } catch (const boost::interprocess::interprocess_exception& ex) {
        std::cerr << "boost::interprocess::interprocess_exception: " << ex.what()
                  << std::endl;
      } catch (const std::exception& ex) {
        std::cerr << "std::exception: " << ex.what() << std::endl;
      } catch (...) {
        std::cerr << "unhandled exception\n";
      }
    }
    

    consumer.cpp

    // Standard Library
    #include <iostream>
    #include <thread>
    #include <utility>
    
    // Boost.Interprocess
    #include <boost/interprocess/managed_shared_memory.hpp>
    #include <boost/interprocess/sync/named_condition.hpp>
    #include <boost/interprocess/sync/named_mutex.hpp>
    
    int main() {
      std::cout << "Started Consumer" << std::endl;
    
      try {
        std::cout << "Consumer: Open/Create shared memory segment" << std::endl;
        boost::interprocess::managed_shared_memory managed_shm{
            boost::interprocess::open_or_create, "SharedMemory_Segment", 1024};
        std::cout << "Consumer: Open/Create mutex" << std::endl;
        boost::interprocess::named_mutex mutex{boost::interprocess::open_or_create,
                                               "SharedMemory_Mutex"};
        std::cout << "Consumer: Open/Create condition" << std::endl;
        boost::interprocess::named_condition condition_read{
            boost::interprocess::open_or_create, "SharedMemory_ConditionRead"};
        boost::interprocess::named_condition condition_write{
            boost::interprocess::open_or_create, "SharedMemory_ConditionWrite"};
    
        std::cout << "Consumer: Start work" << std::endl;
    
        do {
          std::cout << "Consumer: Try to get the lock for the shared mutex "
                       "(potential blocking)"
                    << std::endl;
          boost::interprocess::scoped_lock<boost::interprocess::named_mutex> lock{
              mutex};
    
          std::cout << "Consumer: Wait for Producer" << std::endl;
          condition_write.wait(lock);
    
          std::cout << "Consumer: Read data" << std::endl;
          std::pair<int*, int> p = managed_shm.find<int>("SharedMemory_Data");
    
          if (p.first) {
            std::cout << "Consumer: Found data = " << *p.first << std::endl;
    
            std::cout << "Consumer: Destroy data" << std::endl;
            managed_shm.destroy<int>("SharedMemory_Data");
          }
    
          std::cout << "Consumer: Unlock the mutex" << std::endl;
          lock.unlock();
    
          std::cout << "Consumer: Notify Producer" << std::endl;
          condition_read.notify_one();
        } while (true);
      } catch (const boost::interprocess::interprocess_exception& ex) {
        std::cerr << "boost::interprocess::interprocess_exception: " << ex.what()
                  << std::endl;
      } catch (const std::exception& ex) {
        std::cerr << "std::exception: " << ex.what() << std::endl;
      } catch (...) {
        std::cerr << "unhandled exception\n";
      }
    }
    

    我的问题是:

    1. 上述四项要求是否有任何问题?
    2. 我的代码有什么问题?什么是不必要的,太复杂的或简单的错误? (例如,是否需要两个condition_variables?这两个流程是否需要调用notify_onewait?...)
    3. 任何指导都对我很有帮助。我此刻感到有些愚蠢。

      我正在使用Boost 1.59.0,Microsoft Visual C ++(MSVC)19.11.25547和Windows 10。

0 个答案:

没有答案