如何确保iocp接收中的线程安全?
How to ensure thread safe in iocp receive?
DWORD bytes;
ULONG_PTR key; ChatOverlappedData* ol;
if (!GetQueuedCompletionStatus(hComp_, &bytes, &key, (LPOVERLAPPED*)&ol, 0)) {
return false;
}
int type = ol->getNetType();
if (type == net::kAction_Accept) {
onAccept(ol, bytes, key);
} else if (type == net::kAction_Recv) {
onRecv(ol, bytes, key);
} else if (type == net::kAction_Send) {
}
return true;
考虑以下场景,
客户端alice
向服务器发送了两条命令,由三个数据包组成,p1
p2
p3
。前两个包构成第一个命令c1
,第三个包构成第二个命令c2
。在函数onRecv
中,服务器需要将数据包推送到某种命令缓冲区,以形成完整的命令。
但是假设有3个线程t1
t2
t3
,每个线程得到一个数据包(p1
,p2
,p3
) 来自 GetQueuedCompletionStatus
,
由于 windows 是抢占式操作系统,线程 t2
可以在 t1
、t3
之前 运行。结果命令缓冲区将是 p2
->p1
->p3
或 p2
->p3
->p1
.
数据包推送到命令缓冲区的动作如何保证线程安全?
最简单的解决方案是在每个方向上每个套接字只尝试一个重叠的 I/O 请求。所以 post 一个重叠的读取操作,当它完成时, post 当你处理完第一个时另一个。
发布多个这样的操作非常复杂,因为即使完成将按顺序 posted,处理完成的线程可能会乱序执行,您必须进行一些痛苦和复杂的跟踪.
post在同一连接的同一方向上执行多个重叠操作的好处非常非常小。它几乎永远不足以证明额外的复杂性是合理的。对于处理大量连接的服务器,通常根本不值得这样做,因为额外的内存消耗(或使用较小的缓冲区大小)实际上会使性能变差。
IOCP 的主要好处是更有效地发现哪些连接需要工作,并将该工作有效地分配给线程池。这就是最大 800 个连接的服务器与可以毫不费力地处理 10,000 个连接的服务器之间的区别。
DWORD bytes;
ULONG_PTR key; ChatOverlappedData* ol;
if (!GetQueuedCompletionStatus(hComp_, &bytes, &key, (LPOVERLAPPED*)&ol, 0)) {
return false;
}
int type = ol->getNetType();
if (type == net::kAction_Accept) {
onAccept(ol, bytes, key);
} else if (type == net::kAction_Recv) {
onRecv(ol, bytes, key);
} else if (type == net::kAction_Send) {
}
return true;
考虑以下场景,
客户端alice
向服务器发送了两条命令,由三个数据包组成,p1
p2
p3
。前两个包构成第一个命令c1
,第三个包构成第二个命令c2
。在函数onRecv
中,服务器需要将数据包推送到某种命令缓冲区,以形成完整的命令。
但是假设有3个线程t1
t2
t3
,每个线程得到一个数据包(p1
,p2
,p3
) 来自 GetQueuedCompletionStatus
,
由于 windows 是抢占式操作系统,线程 t2
可以在 t1
、t3
之前 运行。结果命令缓冲区将是 p2
->p1
->p3
或 p2
->p3
->p1
.
数据包推送到命令缓冲区的动作如何保证线程安全?
最简单的解决方案是在每个方向上每个套接字只尝试一个重叠的 I/O 请求。所以 post 一个重叠的读取操作,当它完成时, post 当你处理完第一个时另一个。
发布多个这样的操作非常复杂,因为即使完成将按顺序 posted,处理完成的线程可能会乱序执行,您必须进行一些痛苦和复杂的跟踪.
post在同一连接的同一方向上执行多个重叠操作的好处非常非常小。它几乎永远不足以证明额外的复杂性是合理的。对于处理大量连接的服务器,通常根本不值得这样做,因为额外的内存消耗(或使用较小的缓冲区大小)实际上会使性能变差。
IOCP 的主要好处是更有效地发现哪些连接需要工作,并将该工作有效地分配给线程池。这就是最大 800 个连接的服务器与可以毫不费力地处理 10,000 个连接的服务器之间的区别。