Я пытаюсь создать симуляцию с помощью библиотеки boost, но столкнулся с проблемой асинхронной связи процессов. В нашем случае есть два процесса, которые отправляют/принимают сообщения от/друг к другу (используя команды isend и ireceive). Если я жду, когда все команды отправки/получения завершатся, тогда все будет в порядке. Итак, это мой рабочий код:
boost::mpi::communicator* comm;
// Initialize MPI and etc.
...
std::vector<boost::mpi::request> sendRequests;
std::vector<boost::mpi::request> receiveRequests;
for(int i=0; i< 10; i++){
receiveRequests.push_back(comm->irecv(0, 3000, receivedMessage));
sendRequests.push_back(comm->isend(1, 3000, sentMessage));
boost::mpi::wait_all(receiveRequests.begin(), receiveRequests.end());
receiveRequests.clear();
}
Однако я хочу отменить получение сообщений, если потребуется слишком много времени. Итак, я пытаюсь проверить, завершено ли сообщение или нет, используя функцию тестирования и отмены. Итак, я изменил код, как показано ниже:
boost::mpi::communicator* comm;
// Initialize MPI and etc.
...
std::vector<boost::mpi::request> sendRequests;
std::vector<boost::mpi::request> receiveRequests;
for(int i=0; i< 10; i++){
receiveRequests.push_back(comm->irecv(0, 3000, receivedMessage));
sendRequests.push_back(comm->isend(1, 3000, sentMessage));
vector<boost::mpi::request>::iterator it = receiveRequests.begin();
while(it != receiveRequests.end()){
if(!((*it).test()))
(*it).cancel();
receiveRequests.erase(it);
}
}
Теперь моя программа выходит из строя, и я получаю эту ошибку после первой итерации цикла:
terminate called after throwing an instance of 'std::length_error'
what(): vector::_M_fill_insert
terminate called after throwing an instance of 'std::bad_alloc'
what(): std::bad_alloc
terminate called after throwing an instance of 'boost::exception_detail::clone_impl<boost::exception_detail::error_info_injector<boost::mpi::exception> >'
what(): MPI_Test: Message truncated, error stack:
PMPI_Test(168)....................: MPI_Test(request=0x13bba24, flag=0x7fff081a7bd4, status=0x7fff081a7ba0) failed
MPIR_Test_impl(63)................:
MPIDI_CH3U_Receive_data_found(129): Message from rank 0 and tag 3000 truncated; 670 bytes received but buffer size is 577
Итак, я хотел бы знать, как разрешить эту ошибку.
Наконец, я понял это. Это было просто из-за состояния гонки между методами тестирования и отмены. Поскольку во время выполнения существует сотни запросов на сообщения, иногда возникает такая ситуация. После тестирования запроса программа не может отменить ее, потому что она только что закончилась (после метода тестирования, но до метода отмены). Вот почему это происходит нерегулярно. Итак, мне пришлось изменить способ, что я хотел сделать, и удалить метод отмены.
Откуда it
? Это нигде
Обратите внимание, что push_back может перераспределять и это делает недействительными любые ожидающие итераторы.
Также обратите внимание, что вам необходимо условно увеличить it
если вы сделали удаление. Типичный шаблон
it = receiveRequests.erase(it);
Обновление. Я вижу, что вы добавили информацию на вопрос. Вероятно, это должно быть:
vector<boost::mpi::request>::iterator it = receiveRequests.begin();
while(it != receiveRequests.end()){
if(!((*it).test()))
(*it).cancel();
it = receiveRequests.erase(it);
}
Я не уверен, почему вы всегда удаляете каждый запрос на получение. Я предполагаю, что намерение