C ++奇怪的异步行为

时间:2017-11-06 22:35:36

标签: c++ multithreading asynchronous boost

请注意,由于MinGW缺少线程类支持,因此我使用了boost async。

所以,我想每5秒发送一个数据包,并决定使用boost::asyncstd::async)来达到此目的。

这是我用来发送数据包的函数(这实际上是复制到缓冲区并在主应用程序循环中发送 - nvm - 它在异步方法之外工作正常!)

m_sendBuf = new char[1024]; // allocate buffer

[..]

bool CNetwork::Send(const void* sourceBuffer, size_t size) {
    size_t bufDif = m_sendBufSize - m_sendInBufPos;
    if (size > bufDif) {
        return false;
    }

    memcpy(m_sendBuf + m_sendInBufPos, sourceBuffer, size);
    m_sendInBufPos += size;
    return true;
}

数据包发送代码:

struct TestPacket {
    unsigned char type;
    int code;
};


void SendPacket() {
    TestPacket myPacket{};

    myPacket.type = 10;
    myPacket.code = 1234;

    Send(&TestPacket, sizeof(myPacket));
}

异步代码:

void StartPacketSending() {
    SendPacket();
    std::this_thread::sleep_for(std::chrono::seconds{5});
    StartPacketSending(); // Recursive endless call
}

boost::async(boost::launch::async, &StartPacketSending);

好的。所以问题是,当我从异步方法调用SendPacket()时,收到的数据包在服务器端出错并且数据与指定的数据不同。在异步调用之外调用时不会发生这种情况。

这里发生了什么?我没有想法。

1 个答案:

答案 0 :(得分:0)

我想我的头脑缠绕在你身边。您正在将所有未发送的内容加载到一个线程中的缓冲区中,然后在另一个线程中将其刷新。即使认为数据包没有重叠(假设它们被足够快地消耗),你仍然要同步所有共享数据。

m_sendBufm_sendInPosm_sendBufSize都是从主线程中读取的,可能是在memcpy或缓冲区大小逻辑正在运行时。我怀疑你必须使用一个正确的队列来让你的程序长期运行,但尝试使用互斥锁来保护这些变量。

正如其他评论者所指出的那样,C ++不支持无限递归,但这可能不会导致您的格式错误的数据包。