典型的なクライアント サーバー モデルに従う、mpi を使用する C++ プログラムがあります。クライアントの各 mpi インスタンスは、サーバーの対応する mpi インスタンスに接続します。これは、遅延を追加してテストを行うまでは比較的うまく機能していました (正確には 1 秒の遅延が追加されました)。
問題: 場合によっては、サーバー プロセスの 1 つがクライアントが接続していないと認識しているのに、クライアントが接続していると認識していることがあります。つまり、gdb を使用した後、サーバーは accept() で待機していますが、クライアントは過去の connect() を続行しています。したがって、サーバーが接続していないと考えているときに、クライアントは接続したと考えているように見えます。
私の最善の推測は、どこかに sock-option を設定する必要があるということですが、仲間のプログラマーと話したり、グーグルで調べたりしても、役立つ結果は得られませんでした。
編集: MPI プロセスには 2 つのセットがあります (したがって、mpirun への 2 つの異なる呼び出し)。accept() および connect() 呼び出しは、MPI プロセスの 2 つのセットの間にあるソケット用です。オープンパイです。
コード(実際には他の誰かのコードから)[縮小]:
クライアント (接続コード): (m_socket は実際のソケットです)
if (-1 == m_socket)
{
perror("cannot create socket");
exit(EXIT_FAILURE);
}
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
res = inet_pton(AF_INET, host_ip, &addr.sin_addr);
if (0 > res)
{
perror("error: first parameter is not a valid address family");
close(m_socket);
exit(EXIT_FAILURE);
}
else if (0 == res)
{
perror("error: second parameter does not contain valid IP address");
close(m_socket);
exit(EXIT_FAILURE);
}
//backoff
for (int sec = 1; sec < 20000; sec++ )
{
int ret;
if (0 == (ret = connect(m_socket, (struct sockaddr *)&addr, sizeof(addr))))
{
return;
}
sleep(1);
close(m_socket);
m_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
}
perror("connect failed");
close(m_socket);
exit(EXIT_FAILURE);
サーバー: (m_socket は実際のソケットです)
int socket = ::accept(m_socket, NULL, NULL);
if(socket < 0)
{
fprintf(stderr, "accept() failed: %s\n", strerror(errno));
close(m_socket);
exit(EXIT_FAILURE);
}