2013-05-22 2 views
1

У меня есть программа на C++, использующая mpi, которая следует за типичной моделью клиентского сервера. Каждый экземпляр mpi клиента подключается к соответствующему экземпляру mpi сервера. Это работало относительно хорошо, пока мне не пришлось делать некоторые тесты с добавленной задержкой (точнее, 1 секунду дополнительной латентности).Клиент подключается к серверу, но сервер не считает, что клиент подключился к C++

Проблема: Иногда один из процессов сервера не считает, что клиент подключился, но клиент считает, что он подключен. т. е. после использования gdb сервер ожидает в accept(), но клиент продолжает использовать предыдущий connect(). Таким образом, похоже, клиент считает, что он подключен, когда сервер не считает, что он подключен.

Мое лучшее предположение, что мне нужно установить опцию-носок где-нибудь, однако общение с другими программистами и поисковой системой не принесло никаких полезных результатов.

EDIT: Существует два набора процессов MPI (так что два разных вызова mpirun), вызовы accept() и connect() предназначены для сокетов, которые находятся между двумя наборами процессов MPI. Это openmpi.

код (от чужого кода, на самом деле) [уменьшить]:

Client (подключение кода): (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 фактического гнезда)

+0

Являются ли клиент и сервер запущены на разных хостах? Вы уверены, что подключили клиента к правильному IP-порту? – EJP

+0

Уверен, он иногда работает и иногда терпит неудачу с теми же аргументами запуска. Это находится на том же хосте. – user2411577

+0

Звучит как состояние гонки для меня ... ваш серверный код многопоточен? Если да, то как обрабатывается многопоточность по отношению к сокетам? Возможно ли, что сокет, о котором идет речь, был возвращен accept(), а затем каким-то образом провалился через трещины, и поэтому сервер снова вернулся к блокировке accept(), а «потерянный» сокет не обрабатывается каким-либо другим потоком ? –

ответ

0

Похоже, что вы пытаетесь выполнить соединение/принимать вручную, а не с MPI. Вы можете взглянуть на пример на Deino (http://mpi.deino.net/mpi_functions/MPI_Comm_accept.html), если вы пытаетесь использовать MPI для своих соединений.

В качестве альтернативы вам может потребоваться более общий учебник (некоторые из которых можно найти здесь: http://www.mcs.anl.gov/research/projects/mpi/tutorial/) MPI, чтобы понять, как работает связь. Большую часть времени и приложения не использует Connect/Accept для связи, но использует MPI Communicators для настройки механизмов связи между процессами. Это другая модель (SPMD, в отличие от MPMD).

Смежные вопросы