나는 win apis를 호출하여 C#으로 IOCP 서버를 만들고 있습니다. 1 개의 스레드 연결을 허용하고 CPU 코어에 따라 작업자 스레드가 있습니다.IOCP 스레드 처리
내 문제는 다음 코드 단편을 기반으로 같은 데이터를 동시에 처리하려고하는 2 개의 스레드를 얻게되어 해결책이 무엇인지 또는이 문제가 무엇인지 알 수 있습니까?
public class WorkerThread
{
public void Worker(NetSharedData data)
{
IntPtr bytestransfer = Marshal.AllocHGlobal(sizeof(UInt32));
IntPtr clientid = Marshal.AllocHGlobal(sizeof(UInt32));
IntPtr poverlapped = Marshal.AllocHGlobal(sizeof(UInt32));
Console.WriteLine("Worker thread running");
while (true)
{
Marshal.WriteInt32(clientid, 0);
Marshal.WriteInt32(bytestransfer, 0);
if (SocketInvoke.GetQueuedCompletionStatus(data.completionport, bytestransfer, clientid, poverlapped, SocketInvoke.INFINITE) == true)
{
if (Marshal.ReadInt32(poverlapped) == 0)
{
//thread shutdown
Console.WriteLine("Worker thread shutdown");
break;
}
Client client = data.Clients[Marshal.ReadInt32(clientid)];
if (Marshal.ReadInt32(bytestransfer) != 0)
{
if (client.operationtype == SocketInvoke.FD_WRITE)
{
if (client.send_data.ispending_operation == true)
{
client.SendLeft((uint)Marshal.ReadInt32(bytestransfer));
break;
}
}
if (client.operationtype == SocketInvoke.FD_READ)
{
if (!client.Recv((uint)Marshal.ReadInt32(bytestransfer)))
{
client.Close();
break;
}
if (data.OnRecv(client) == true)
{
//SendLeft test
}
}
}
}
}
}
}
/*
//THIS IS A CODE SNIPPET THAT BELONGS TO THE ACCEPT THREAD CLASS
*/
public virtual bool Recv(uint expected_data_transfer)
{
IntPtr pwsabuf;
IntPtr wsaoverlapped;
IntPtr bytes_recv = Marshal.AllocHGlobal(sizeof(int));
IntPtr flags = Marshal.AllocHGlobal(sizeof(int));
Marshal.WriteInt32(flags, 0);
set_total_transfer(SocketInvoke.FD_READ, expected_data_transfer);
pwsabuf = recv_data.rtn_wsabuffarray(recv_data.buffer, (uint)recv_data.bufflen);
wsaoverlapped = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(SocketInvoke.WSAOVERLAPPED)));
Marshal.StructureToPtr(overlapped, wsaoverlapped, false);
SocketInvoke.FillMemory(wsaoverlapped, (uint)Marshal.SizeOf(typeof(SocketInvoke.WSAOVERLAPPED)), 0);
unsafe
{
setoptype(SocketInvoke.FD_READ);
if (SocketInvoke.WSARecv(Convert.ToUInt32(sock.Handle.ToInt32()), pwsabuf,
(uint)1, bytes_recv, flags, wsaoverlapped, (IntPtr)null) == SocketInvoke.SOCKET_ERROR)
{
if (Marshal.GetLastWin32Error() != SocketInvoke.WSA_IO_PENDING)
{
return false;
}
return true;
}
}
return true;
}
또한 WSASend 및 WSARecv?를 사용하여 데이터의 부분 전송 또는 부분 수신을 얻을 수 있습니까?
1) 이유는 무엇입니까? 관리되는 비동기 소켓 메소드를 사용하거나 C 또는 C++의 소켓 코드 전체를 수행하고 좋은 깨끗한 인터페이스를 통해이를 관리 코드에 표시하십시오. 2) 읽기 또는 쓰기 작업마다 고유 한 중첩 구조가 필요합니다. –