将数组作为多线程应用程序中函数的返回传递

passing array as return from function in multi threaded app

本文关键字:函数 返回 应用程序 数组 多线程      更新时间:2023-10-16

我尝试制作多线程代码,在某些步骤中,我必须检索堆上的数组。
这是代码:
以下函数将调用另一个名为 read_bi5_to_bin 的函数,它将传递给它初始化为 nullptr data_bin_buffer 的无符号 char*

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::d eCompress。 这是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::d ecompress 中将在堆上制作一个名为 outBuffer 的数组,我需要在 data_bin_buffer
中检索read_bi5_main这个缓冲区这是 N47::LZMA::d eCompression 的代码

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,它会给出另一个错误。我不应该初始化指针吗???

您的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的指针。

// 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;
}

并且它从不返回或释放它存储在buffer_decompressed中的值。

哎呀。

我在代码中发现了问题。
这是我将指向无符号字符的指针传递给read_bi5_to_bin的方式。
起初我认为传递指针变量是正确的"好像我正在传递左值引用"但我错了很多.reference 与指针不同。
指针变量是类型的左值变量 pointer.so 它被复制到函数中,在函数中创建新的左值变量。新变量具有相同的指针传递值。此值是数组中第一个无符号字符的地址。
但我真正需要的是将指针传递到指针到无符号字符。然后指针到指针将被复制到函数中。复制变量的值将是指向无符号字符的指针的地址。这就是我需要从函数中检索的内容。
我使用&运算符来获取指向指针的指针,然后我阅读了非常有用的评论,建议使用**,所以我将代码更改为使用**.voila,它的工作原理
是修改后的代码:

read_bi5_to_bin_lock2.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 = 0 ;
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_lock2.unlock();

这是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);

非常感谢DavidSchwartz的非常有用的评论。