Multithreading 尝试在2个线程中运行asio时,在(ntdll.dll)访问冲突读取位置引发异常

Multithreading 尝试在2个线程中运行asio时,在(ntdll.dll)访问冲突读取位置引发异常,multithreading,boost-asio,Multithreading,Boost Asio,我不熟悉多线程。我制作的程序在单线程时运行良好。但当我添加另一个线程来运行asio io服务时,“主线程运行相同的io服务”,它会给我以下错误: 在(ntdll.dll)访问冲突读取位置引发异常 我使用vs 2017,并尝试使用调用堆栈来定位错误,但它发生在我没有其源代码的ntdll.dll代码中。 此外,我试图排除部分代码,但当异步函数从io服务返回时,似乎会发生错误。 程序很大,所以我没有输入代码。 我想知道是否有办法使用vs2017将ntdll.dll错误链接到导致此错误的源代码部分。 错

我不熟悉多线程。我制作的程序在单线程时运行良好。但当我添加另一个线程来运行asio io服务时,“主线程运行相同的io服务”,它会给我以下错误:
在(ntdll.dll)访问冲突读取位置引发异常

我使用vs 2017,并尝试使用调用堆栈来定位错误,但它发生在我没有其源代码的ntdll.dll代码中。
此外,我试图排除部分代码,但当异步函数从io服务返回时,似乎会发生错误。
程序很大,所以我没有输入代码。
我想知道是否有办法使用vs2017将ntdll.dll错误链接到导致此错误的源代码部分。
错误时的调用堆栈onlu显示:
ntdll.dll__除_handler4()
ntdll.dll!ExecuteHandler2@20()
ntdll.dll!ExecuteHandler@20()

如果需要文件,我会把它们的代码放进去。
谢谢

更新:
即使我在锁定互斥锁后启动此函数,它仍会抛出很多错误。
我认为内存使用有问题。这会导致访问冲突

std::string HTTPRequest::output_compressed_file_2(boost::shared_ptr<unsigned char> data_bin_buffer, size_t buffer_size, const char * file_name)
{
    std::string file_name_path_string = file_name; 
    std::ofstream ofs2(file_name_path_string, std::ios::binary); 
    ofs2.write(reinterpret_cast<const char*>(data_bin_buffer.get()), buffer_size);

    ofs2.close();
    return file_name_path_string;
}
哦。现在我。我仍然在代码中看到同样的问题。主要是,它(非常)过于复杂。我看到了许多值得注意的事情,但我不确定这是否会有帮助,因为上次也没什么帮助:

  • boost::shared_ptr data_bin_buffer=boost::make_shared()

    为什么要创建单字节的“缓冲区”?为什么要将它们创建为共享资源

  • 您的
    read_bi5_main
    几乎正确地执行了该操作,并且似乎是从或类似的文件中复制的

  • n47::read_bi5
    返回在
    raw_size
    中读取的字节,并将其用作有效的缓冲区大小

    我找不到
    read_bi5_to_bin
    的文档,因此不知道到底是如何使用该bin_缓冲区的,但我可以看出您可能在使用它:

    output_compressed_file_2(data_bin_buffer, raw_size, filename_2_bin);
    
    在这里,您将
    数据\u bin\u buffer
    视为指向任何大小的
    原始大小的缓冲区,其中唯一有效的大小可能是
    1
    0
    (因为您从未分配更多)

    这就是调用

    即使您使
    read\u bi5\u to\u bin
    对于1字节的bin缓冲区是安全的,这也将是非常无用的,因为一个
    n47::ROW\u SIZE
    是20字节

  • resolver_iterator iterator_connect = boost::asio::async_connect(mSock, iterator_resolve, yield_r[ec]);
    
    您没有注意不要手动迭代解析器结果的建议。现在,您正在加倍执行所有操作(如果您有5个解析器结果,则尝试连接
    (尝试次数-1)*(5+4+3+2+1)
    次)。 除了
    truments-1
    看起来像个错误(循环条件似乎错误,或者循环变量初始值设定项应该为0?),这当然不是您想要/需要的。然而,
    mIrange2
    [sic]的许多(双)递增/递减使得很难预测将进行多少次尝试,以及如何根据日志语句进行编号。事实上,如果存在无限循环的可能性,我也不会感到惊讶

  • mUri
    mUrl
    。这必然会导致错误

  • 总结 我认为清单上的第3条是你在这里撞车的原因。
    在相关新闻中,我为最近的另一个问题创建了一个示例,这让我想起了您的代码:


    也许它可以帮助您了解如何创建更简单的代码来实现您想要实现的目标。我的意思是,您应该得到20%的代码。

    我发现我正在将指向无符号字符“data\u bin\u buffer”的指针作为参数传递给函数read\u bi5\u to\u bin,
    这是如何作为变量处理的,
    在函数内部复制,并为副本分配数组,
    但传递的指针仍为空。
    所以我将数据缓冲区从指针无符号字符改为值无符号字符,
    然后通过&,
    并将此信息传递给read_bi5__bin,
    并解决了问题。
    但我现在有另一个问题。我应该删除还是删除[]和数据\u bin\u缓冲区???

    如果我删除它“而不是数组删除”,那么&data\u bin\u buffer所指向的堆上的数组会发生什么情况

    您需要显示您的代码。你有,通常是因为你没有确保在异步操作期间对象的生存期保持不变(比如缓冲区)。@sehe我搜索了如何上传代码,但他们说不允许上传文件……所以我不知道如何显示代码。我正在试着隔离错误。但是它发生在ntdll.dll上,它不在我的源代码范围内。我不知道该怎么做。是你的代码触发了它,所以找出是什么函数调用触发了错误。您可以在问题文本中显示代码。每个人都是这样做的。我会尝试隔离错误并显示触发错误的代码。thanks@sehe我包括了一些代码,我认为这可能是错误的来源。谢谢你的帮助。你太棒了。我爱你:)
    mSock究竟是如何被“重命名”为mlock的?这似乎很草率
    这行没有改变??它仍然是mSock
    boost::shared_ptr data\u bin_buffer=boost::make_shared()我并不是想让它成为单字节缓冲区。我只是没有改变太多的原始代码,我从read_bi5内部传输数据,所以我只是更改了read_bi5,使用shared_pointer将这个共享指针的原始指针指向未签名的字符。get然后我使用这个指针将文件的内容传递到输出压缩的_file_2,有时候它可以工作,有时候它只有一个字符??我想我只需要指针和大小…我如何分配给指针?它不是array@ahmedallam然后将其设置为数组:或。请记住,99%的时间应该避免使用共享指针。如果您需要一个用于异步操作,请使用1包含所有共享资源
    
    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;
    }
    
    output_compressed_file_2(data_bin_buffer, raw_size, filename_2_bin);
    
    resolver_iterator iterator_connect = boost::asio::async_connect(mSock, iterator_resolve, yield_r[ec]);