多线程 - 在不同类的方法之间传递变量

时间:2014-06-14 04:38:58

标签: c++ multithreading boost

我正在开发一个需要多线程的项目。我有三个线程,其中两个并行运行,一个异步运行,如示例代码所示。我对变量和boost::shared_mutex

有几个问题
  
      
  1. 在方法之间传递矢量和其他变量是否有更优雅的方法?
  2.   
  3. 我们在锁定关键部分时遇到boost::shared_mutex问题。在这种情况下有更好的方法吗?
  4.   

感谢您的帮助。对不起代码的长度。

// A.h
class A{
private:
       std::vector<int> a_data;
public:
       int capture_a(std::vector<int> &data_transfer,boost::shared_mutex &_access,int &flag);
};

// A.cpp
A::capture_a(std::vector<int> &a_data_transfer,boost::shared_mutex &_access,int &a_flag)
{
     // collect data 
     while(true)
     {
        //data input
        a_data.push_back(data);
        if(a_data.size() > N) //a certain limit
        {
             // save a_data
             a_flag = 1;
             boost::unique_lock< boost::shared_mutex > lock(_access);
             //swap with empty array
             // a_data_transfer should be empty
             a_data_transfer.swap(a_data);
        }
        if(boost::thread_interrupted&)
        {
             std::cout << " Thread interrupted" << std::endl;
             return 0;
        }
     }
}

// B.h
class B{
private:
    std::vector<int> b_data;
public:
    int capture_b(std::vector<int> &b_data_transfer, boost::shared_mutex &_access,int &a_flag,int &b_flag);
};

// B.cpp
B::capture_b(std::vector<int> &b_data_transfer, boost::shared_mutex &_access, int &a_flag,int &b_flag)
{
     // collect data 
     while(true)
     {
        //data input
        b_data.push_back(data);
        if(a_flag == 1) //a_flag is true
        {
             boost::unique_lock< boost::shared_mutex > lock(_access);
             b_data_transfer.swap(b_data);
             b_flag = 1;
             // save data
             a_flag = 0;

        }
        if(boost::thread_interrupted&)
        {
             std::cout << " Thread interrupted" << std::endl;
             return 0;
        }
     }
}

// C.h
class C
{
private: 
      std::vector<int> c_data;
public: 
      int compute_c(std::vector<int> &a_data,std::vector<int> &b_data,boost::shared_mutex &_access, int &b_flag);
}

// C.cpp
C::compute_c(std::vector<int> &a_data,std::vector<int> &b_data,boost::shared_mutex &_access,int &b_flag)
{
    while(true) {
     if(b_flag == 1)
     {
          boost::unique_lock< boost::shared_mutex > lock(_access);
          // compute on c
          c_data = a_data + b_data;    // for example
          // save c_data
          b_flag = 0;
          a_data.clear();
          b_data.clear();
     }
     if(boost::thread_interrupted&)
     {
         std::cout << " Thread interrupted" << std::endl;
         return 0;
     }
   }
}

int main()
{

     std::vector<int> a_data_transfer, b_data_transfer;
     boost::shared_mutex _access;
     int a_flag = 0, b_flag = 0;
     boost::thread t1(&A::capture_a,boost::ref(a_data_transfer),boost::ref(_access),boost::ref(a_flag));
     boost::thread t2(&B::capture_b,boost::ref(b_data_transfer),boost::ref(_access),boost::ref(a_flag),boost::ref(b_flag));
     boost::thread t3(&C::compute_c,boost::ref(a_data_transfer),boost::ref(b_data_transfer),boost::ref(_access),boost::ref(b_flag));
     // Wait for Enter 
     char ch;
     cin.get(ch);

     // Ask thread to stop
     t1.interrupt();
     t2.interrupt();
     t3.interrupt();

     // Join - wait when thread actually exits
     t1.join();
     t2.join();
     t3.join();
}

********** EDIT *************

我想要实现的目标是:

  
      
  1. A和B应该并行运行,当A中满足某个条件时,a_datab_data应该转移到C.转移数据后,向量应继续收集新的数据。
  2.   
  3. C应该接受a_datab_data并在标志为真时执行计算。
  4.   

boost :: shared_mutex问题 - 我们希望交换时a_data_transfer为空。它有时会发生但不是所有时间都会发生。我需要一种方法来确保代码正常运行。

1 个答案:

答案 0 :(得分:2)

  

在方法之间传递矢量和其他变量是否有更优雅的方法?

嗯...优雅是一种品味问题....但您可能希望将共享数据封装到某个类或结构中,包含:

  1. 共享数据
  2. 保护它们的互斥(或互斥)
  3. 处理共享数据并适当锁定它们的方法。
  4. 这将简化您需要传递给线程执行的数据量。

    可能你已经知道这一点,但重要的是要认识到一个线程不是一个代码元素,而只是一个调度概念。事实上,在现代库中,线程由对象表示,这只是为了方便我们。

      

    我们在锁定关键部分时遇到boost :: shared_mutex问题。在这种情况下有更好的方法吗?

    没有关于实际问题的进一步细节很难说。

    一些注意事项:

    1. shared_mutex是一个读/写互斥锁。旨在允许多个同时读者,但只有一个作家。从代码中看来你只能编写(unique_lock),所以也许你可以使用更简单的互斥锁。
    2. 在我看来,引入了互斥锁来保护数据。而且您必须注意锁定最少的时间,并且只有在真正访问共享数据时,才能平衡使设置操作成为原子的需要。你有一个保护两个向量的互斥锁。没关系,但你可能想要考虑是否需要。