在外部进程中调用函数的最快,最安全的方法

时间:2015-01-26 13:22:22

标签: c++ synchronization extern interprocess

问题描述:

我们需要尽快调用extern进程中的函数。 Boost进程间共享内存用于通信。 extern进程是mpi master或单个可执行文件。函数的计算时间介于1ms和1s之间。该函数最多应调用10 ^ 8-10 ^ 9次。

我已经尝试了很多可能性,但我仍然遇到了一些问题。在这里,我将介绍两个最佳工作实现

版本1(使用intreprocess条件)

主处理

bool calculate(double& result, std::vector<double> c){
            // data_ptr is a structure in shared memoty
            data_ptr_->validCalculation = false;
            bool timeout = false;
            // write data (cVec_ is a vector in shared memory )

            cVec_->clear();
            for (int i = 0; i < c.size(); ++i)  
            {
                cVec_->push_back(c[i]);
            }
            // cond_input_data is boost interprocess condition
            data_ptr_->cond_input_data.notify_one();

            boost::system_time const waittime = boost::get_system_time() + boost::posix_time::seconds(maxWaitTime_in_sec);

            // lock slave process
            scoped_lock<interprocess_mutex> lock_output(data_ptr_->mutex_output);

            // wait till data calculated

            timeout = !(data_ptr_->cond_output_data.timed_wait(lock_output, waittime)); // true if timeout, false if no timeout

            if (!timeout)
            {
                // get result
                result = *result_;
                return data_ptr_->validCalculation;
            }
            else
            {
                return false;
            }
        };

外部流程运行一个while循环(直到中止条件已满)

do {    

    scoped_lock<interprocess_mutex> lock_input(data_ptr_->mutex_input);
    boost::system_time const waittime = boost::get_system_time() + boost::posix_time::seconds(maxWaitTime_in_sec);
    timeout = !(data_ptr_->cond_input_data.timed_wait(lock_input, waittime)); // true if timeout, false if no timeout



    if (!timeout)
    {
        if (!*abort_flag_) {

            c.clear();
            for (int i = 0; i < (*cVec_).size(); ++i)  //Insert data in the vector
            {
                c.push_back(cVec_->at(i));
            }

            // calculate value
            if (call_of_function_here(result, c)) { // valid calculation ?
                *result_ = result;
                data_ptr_->validCalculation = true;
            }
        }
    }

    //Notify the other process that the data is avalible or we dont get the input data
    data_ptr_->cond_output_data.notify_one();           


} while (!*abort_flag_); // while abort flag is not set, check if some values should be calculated

这是最好的工作版本,但如果计算时间很短(约1毫秒),有时它会保持不变。我认为,如果main-process达到

,就会发生这种情况
        data_ptr_->cond_input_data.notify_one();

早些时候,extern进程正在等待

timeout = !(data_ptr_->cond_input_data.timed_wait(lock_input, waittime)); 
等待条件。所以我们可能有某种同步问题。 第二个条件没有帮助(即仅在未设置输入数据时等待,类似于带有message_in标志的anonymous condition example)。因为,在第二个进程等待通知之前,一个进程仍然可以通知另一个进程。

版本2(使用布尔标志和while循环有一些延迟) 主处理

bool calculate(double& result, std::vector<double> c){

            data_ptr_->validCalculation = false;
            bool timeout = false;
            // write data
            cVec_->clear();
            for (int i = 0; i < c.size(); ++i)  //Insert data in the vector
            {
                cVec_->push_back(c[i]);
            }

           // this is the flag in shared memory used for communication
            *calc_flag_ = true;

            clock_t test_begin = clock();
            clock_t calc_time_begin = clock();
            do
            {
                calc_time_begin = clock();
                boost::this_thread::sleep(boost::posix_time::milliseconds(while_loop_delay_m_s));
                // wait till data calculated
                timeout = (double(calc_time_begin - test_begin) / CLOCKS_PER_SEC > maxWaitTime_in_sec);
            } while (*(calc_flag_) && !timeout);

            if (!timeout)
            {
                // get result
                result = *result_;
                return data_ptr_->validCalculation;
            }
            else
            {
                return false;
            }

        };

和外部流程

do {    

    // we wait till input data is set
    wait_begin = clock();
    do
    {           
        wait_end = clock();
        timeout = (double(wait_end - wait_begin) / CLOCKS_PER_SEC > maxWaitTime_in_sec);
        boost::this_thread::sleep(boost::posix_time::milliseconds(while_loop_delay_m_s));
    } while (!(*calc_flag_) && !(*abort_flag_) && !timeout);


    if (!timeout)
    {
        if (!*abort_flag_) {

            c.clear();
            for (int i = 0; i < (*cVec_).size(); ++i)  //Insert data in the vector
            {
                c.push_back(cVec_->at(i));
            }

            // calculate value
            if (call_of_local_function(result, c)) { // valid calculation ?
                *result_ = result;
                data_ptr_->validCalculation = true;
            }
        }
    }

    //Notify the other process that the data is avalible or we dont get the input data
    *calc_flag_ = false;


} while (!*abort_flag_); // while abort flag is not set, check if some values should be calculated

此版本中的问题是延迟时间。由于我们的计算时间接近1ms,因此我们必须将延迟设置为至少为此值。对于较小的延迟,CPU负载较高,对于较高的延迟,由于没有必要的等待时间,我们会失去很多性能

您是否知道如何改进其中一个版本?或者可能有更好的解决方案?

THX。

0 个答案:

没有答案