我可以使用 std::shared_ptr 在 IOCP 中包装每个 I/O 数据吗?

Posted

技术标签:

【中文标题】我可以使用 std::shared_ptr 在 IOCP 中包装每个 I/O 数据吗?【英文标题】:Can I use std::shared_ptr to wrap per I/O data in IOCP? 【发布时间】:2012-08-06 21:44:02 【问题描述】:

我正在开发一个使用 IOCP 的客户端应用程序。

我的每个 I/O 数据类派生自 WSAOVERLAPPED:

class IoRequest : public WSAOVERLAPPED

...
;

而在执行异步 I/O 操作时,我是这样使用的:

 // WSASend - this is done in my main thread.
    IoRequest *pIoRequest = new IoRequest;
    pIoRequest->SetSocket(m_socket);
    pIoRequest->SetBuffer(vecCommandData);
    pIoRequest->SetOperationType(OP_TYPE_SEND);
    WSASend(m_socket, pIoRequest->GetWsaBuffer(), 1, NULL, 0, pIoRequest, NULL);


 // WSARecv - this is done in my I/O worker thread.
    GetQueuedCompletionStatus(m_hIocp, &dwNumberOfBytesTransferred, &ulCompletionKey, (LPOVERLAPPED*)&pIoRequest, INFINITE);
    ...
    WSARecv(pIoRequest->GetSocket(), pIoRequest->GetWsaBuffer(), 1, NULL, &(pIoRequest->GetFlags()), pIoRequest, NULL);
    ...

我在我的工作线程例程中重用了我的 IoRequest 实例。我想知道,使用 std::shared_ptr 而不是原始指针来管理我的每个 I/O 数据会有什么问题吗?

所以对于 WSASend(),类似于:

std::shared_ptr<IoRequest> spIoRequest(new IoRequest);
spIoRequest->SetSocket(m_socket);
spIoRequest->SetBuffer(vecCommandData);
spIoRequest->SetOperationType(OP_TYPE_SEND);
WSASend(m_socket, spIoRequest->GetWsaBuffer(), 1, NULL, 0, spIoRequest.get(), NULL);

干杯

【问题讨论】:

【参考方案1】:

除非您在某处拥有std::shared_ptr&lt;IoRequest&gt; 的实时实例,否则您的IoRequest 将在完成处理程序接收之前在发送例程结束时被释放。

【讨论】:

@Remy,感谢您的输入,但我更喜欢自己编辑答案。据我们所知,这种释放可能发生在接收回调的中间。

以上是关于我可以使用 std::shared_ptr 在 IOCP 中包装每个 I/O 数据吗?的主要内容,如果未能解决你的问题,请参考以下文章

在 lambda 中锁定 std::shared_ptr 的复制操作

为啥我不能在 C++0x 中对 std::shared_ptr 的向量执行 std::copy?

SWIG:使用带有 shared_ptr 的 std::map 访问器?

为啥不推荐使用 std::shared_ptr::unique() ?

“预定义”和使用命名空间和 std::shared_ptr 的正确方法是啥?

std :: shared_ptr的错误用法,有人可以帮忙指出问题所在吗?