在多线程应用中将数组作为函数的返回值传递 [英] passing array as return from function in multi threaded app

查看:72
本文介绍了在多线程应用中将数组作为函数的返回值传递的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试编写多线程代码,并在某些步骤中必须检索在堆上创建的数组。

这是代码:

以下函数将调用另一个函数称为read_bi5_to_bin,它将传递给它的未签名char *初始化为nullptr data_bin_buffer

i try to make code which is multithreaded and at certain step i have to retrieve array made on heap.
this is the code:
the following function will call another function called read_bi5_to_bin and it will pass to it unsigned char* initialized as nullptr data_bin_buffer

 int HTTPRequest::read_bi5_main(boost::filesystem::path p, ptime epoch)
{
    boost::unique_lock<boost::mutex> read_bi5_to_bin_lock(m_read_bi5_to_binMutex,boost::defer_lock);

    unsigned char *buffer;
    size_t buffer_size;

    int counter;

    size_t raw_size = 0;

    std::string filename_string = p.generic_string();
    path p2 = p;
    p2.replace_extension(".bin");
    std::string filename_string_2_bin =p2.generic_string() ;

    path p3 = p;
    p3.replace_extension(".csv");
    std::string filename_string_2_csv = p3.generic_string();

    const char *filename = filename_string.c_str();
    const char *filename_2_bin = filename_string_2_bin.c_str();

    const char *filename_2_csv = filename_string_2_csv.c_str();

    if (fs::exists(p) && fs::is_regular(p)) 
    {
        buffer_size = fs::file_size(p);
        buffer = new unsigned char[buffer_size];
    }
    else {
        //??5-17-2020 isolate multithreaded error
        read_bi5_to_bin_lock.lock();
        BOOST_LOG((*mHTTPRequest_LoggingInstance_shared_pointer).mloggerCoutLog) << "Error: couldn't access the data file. |"
            << filename << "|" << std::endl;
        read_bi5_to_bin_lock.unlock();

        return 2;
    }

    std::ifstream fin(filename, std::ifstream::binary);
    //fin.open(filename, std::ifstream::binary);
    fin.read(reinterpret_cast<char*>(buffer), buffer_size);
    fin.close();

    //5-11-2020 the next line will be commented and put in HTTPCLIent constructor
    //mHTTPRequest_Symbol_str= mHTTPRequest_HTTPClient_shared_pointer->Get_mHttpClient_HttpSymbolPrepareGet_shared_pointer()->mSymbol_strGet() ;
    std::size_t pos = mHTTPRequest_Symbol_str.find("JPY");// position of "h_ticks.bi5" in str
    double PV;
    if (pos != std::string::npos)
    {
        PV = PV_YEN_PAIR;
    }
    else
    {
        PV = PV_DOLLAR_PAIR;
    }
    //??5-17-2020 isolate multithreaded error
    read_bi5_to_bin_lock.lock();
    //5-20-2020
    //boost::shared_ptr<unsigned char> data_bin_buffer = boost::make_shared<unsigned char>() ;
    //n47::tick_data *data = n47::read_bi5_to_bin(
    //  buffer, buffer_size, epoch, PV, &raw_size, data_bin_buffer.get());
    unsigned char* data_bin_buffer = nullptr;
    n47::tick_data *data = n47::read_bi5_to_bin(
            buffer, buffer_size, epoch, PV, &raw_size, data_bin_buffer);
    //5-11-2020 here i will save binary file
    //boost::unique_lock<boost::mutex> read_bi5_to_bin_lock(m_read_bi5_to_binMutex);
    std::string file_name_path_string=output_compressed_file_2(data_bin_buffer, raw_size, filename_2_bin);
    read_bi5_to_bin_lock.unlock();

    path file_name_path_2{ file_name_path_string }; 
    buffer_size = 0;    
    if (fs::exists(file_name_path_2) && fs::is_regular(file_name_path_2)) 
    {
        //??5-17-2020 isolate multithreaded error
        read_bi5_to_bin_lock.lock();

        BOOST_LOG((*mHTTPRequest_LoggingInstance_shared_pointer).mloggerCoutLog) << boost::this_thread::get_id() <<"\t we can access the data .bin file. |"
            << filename_2_bin << "| with size ="<< fs::file_size(file_name_path_2) << std::endl;
        read_bi5_to_bin_lock.unlock();

    }
    else {
        //??5-17-2020 isolate multithreaded error
        read_bi5_to_bin_lock.lock();

        BOOST_LOG((*mHTTPRequest_LoggingInstance_shared_pointer).mloggerCoutLog) << "Error: couldn't access the data .bin file. |"
            << filename_2_bin << "|" << std::endl;
        read_bi5_to_bin_lock.unlock();

        return 2;
    }

    n47::tick_data_iterator iter;

    //5-11-2020 here i will save file.csv from data which is pointer to vector to pointers to ticks

    if (data == 0) {
        //??5-17-2020 isolate multithreaded error
        read_bi5_to_bin_lock.lock();

        BOOST_LOG((*mHTTPRequest_LoggingInstance_shared_pointer).mloggerCoutLog) << "Failure: Failed to load the data!" << std::endl;
        read_bi5_to_bin_lock.unlock();

        //5-14-2020 file is empty
        //return 0;
    }
    //5-15-2020 take care that without else ,error happens with empty files because data is pointer to vector of pointers to ticks .so when data is made inside read_bi5 ,it is made as null pointer and later it is assigned to vector if file has ticks.if file does not have ticks ,then it is just returned as null pointer .so when dereferencing null pointer we got error
    else if (data->size() != (raw_size / n47::ROW_SIZE)) {
        //??5-17-2020 isolate multithreaded error
        read_bi5_to_bin_lock.lock();

        BOOST_LOG((*mHTTPRequest_LoggingInstance_shared_pointer).mloggerCoutLog) << "Failure: Loaded " << data->size()
            << " ticks but file size indicates we should have loaded "
            << (raw_size / n47::ROW_SIZE) << std::endl;
        read_bi5_to_bin_lock.unlock();

        //5-14-2020 file is empty
        //return 0;
    }

    //??5-17-2020 isolate multithreaded error
    read_bi5_to_bin_lock.lock();

    BOOST_LOG((*mHTTPRequest_LoggingInstance_shared_pointer).mloggerCoutLog) << "time, bid, bid_vol, ask, ask_vol" << std::endl;
    read_bi5_to_bin_lock.unlock();

    counter = 0;
    std::ofstream out_csv(filename_string_2_csv);
    if (data == 0)
    {

    }
    else if (data != 0)
    {
        ////read_bi5_to_bin_lock.lock();

        for (iter = data->begin(); iter != data->end(); iter++) {
            //5-11-2020 here i will save file.csv from data which is pointer to vector to pointers to ticks>>>>>>>here i should open file stream for output and save data to it
            out_csv << ((*iter)->epoch + (*iter)->td) << ", "
                << (*iter)->bid << ", " << (*iter)->bidv << ", "
                << (*iter)->ask << ", " << (*iter)->askv << std::endl;
            //??5-17-2020 isolate multithreaded error
            read_bi5_to_bin_lock.lock();

            BOOST_LOG((*mHTTPRequest_LoggingInstance_shared_pointer).mloggerCoutLog) <<
                boost::this_thread::get_id() << "\t"<<((*iter)->epoch + (*iter)->td) << ", "
                << (*iter)->bid << ", " << (*iter)->bidv << ", "
                << (*iter)->ask << ", " << (*iter)->askv << std::endl;
            read_bi5_to_bin_lock.unlock();

            counter++;
        }
        ////read_bi5_to_bin_lock.unlock();

    }
    out_csv.close();
    //5-13-2020

    //??5-17-2020 isolate multithreaded error
    read_bi5_to_bin_lock.lock();

    BOOST_LOG((*mHTTPRequest_LoggingInstance_shared_pointer).mloggerCoutLog) << ".end." << std::endl << std::endl
        << "From " << raw_size << " bytes we read " << counter
        << " records." << std::endl
        << raw_size << " / " << n47::ROW_SIZE << " = "
        << (raw_size / n47::ROW_SIZE) << std::endl;
    read_bi5_to_bin_lock.unlock();


    delete data;
    delete[] buffer;    
    delete [] data_bin_buffer;
    return 0;
}

然后在read_bi5_to_bin函数中,将调用另一个函数n47 :: lzma :: decompress。这是read_bi5_to_bin的代码:

then inside read_bi5_to_bin function ,there will be a call to another function n47::lzma::decompress . this is the code of read_bi5_to_bin:

tick_data* read_bi5_to_bin(
    unsigned char *lzma_buffer, size_t lzma_buffer_size, pt::ptime epoch,
    float point_value, size_t *bytes_read, unsigned char* buffer_decompressed) {
    tick_data *result = 0;

    // decompress
    int status;
    buffer_decompressed = n47::lzma::decompress(lzma_buffer,
        lzma_buffer_size, &status, bytes_read);

    if (status != N47_E_OK) 
    {
        bytes_read = 0;
    }
    else {
        // convert to tick data (with read_bin).
        result = read_bin(buffer_decompressed, *bytes_read, epoch, point_value);
        //delete[] buffer;
    }

    return result;
}

然后在n47 :: lzma :: decompress内将要创建一个数组我需要在data_bin_buffer中的read_bi5_main处检索此缓冲区的缓冲区

这是n47 :: lzma :: decompress

then inside n47::lzma::decompress there will be making an array on heap called outBuffer .this buffer i need to retrieve at read_bi5_main in data_bin_buffer
this is code for n47::lzma::decompress

unsigned char *decompress(
        unsigned char *inBuffer, size_t inSize, int *status, size_t *outSize) {
    unsigned char *outBuffer = 0;
    elzma_file_format format = ELZMA_lzma;

    elzma_decompress_handle handle;
    handle = elzma_decompress_alloc();

    if (handle == 0) {
        *status = -1;
    } else {
        // decompression...
        datastream ds(inBuffer, inSize);
        *status = elzma_decompress_run(
            handle,
            inputCallback, static_cast<void*>(&ds),
            outputCallback, static_cast <void*>(&ds),
            format);

        if (*status == ELZMA_E_OK) {
            *outSize = ds.outData.size();
            outBuffer = new unsigned char[ ds.outData.size() ];
            std::copy(ds.outData.begin(), ds.outData.end(), outBuffer);
        }
        elzma_decompress_free(&handle);
    }

    return outBuffer;
}

当我运行此命令时会出错。这里非常有用的一个告诉我这是data_bin_buffer的问题所在,因为它只是一个字节。建议我避免使用共享指针。当我将其转换为普通指针时,如果将其初始化为nullptr,则会出现另一个错误。我不应该初始化指针吗?

when i run this it gives error.a very helpful one here told me that it is the data_bin_buffer which is the problem because it is just one byte.and advised me to avoid shared pointer.when i convert it to normal pointer it gives another error if initialzed it to nullptr.should i not initialize the pointer???

推荐答案

您的 read_bi5_to_bin 代码已损坏。

tick_data* read_bi5_to_bin(
    unsigned char *lzma_buffer, size_t lzma_buffer_size, pt::ptime epoch,
    float point_value, size_t *bytes_read, unsigned char* buffer_decompressed) {
    tick_data *result = 0;

代码接收到一个名为 buffer_decompressed 的指针。

The code receives a pointer called buffer_decompressed.

    // decompress
    int status;
    buffer_decompressed = n47::lzma::decompress(lzma_buffer,
        lzma_buffer_size, &status, bytes_read);

然后,它丢弃接收到的值并获得其他值。

Then it throws away the value it received and gets some other value.

    if (status != N47_E_OK) 
    {
        bytes_read = 0;
    }
    else {
        // convert to tick data (with read_bin).
        result = read_bin(buffer_decompressed, *bytes_read, epoch, point_value);
        //delete[] buffer;
    }

    return result;
}

它从不返回或释放存储在 buffer_decompressed 。

And it never returns or frees the value it stored in buffer_decompressed.

糟糕。

这篇关于在多线程应用中将数组作为函数的返回值传递的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆