проблема многопоточности gsoap (клиент / сервер) - PullRequest
0 голосов
/ 24 августа 2018

У меня есть два приложения, которые взаимодействуют с SOAP запросами друг с другом.Оба интерфейса используют одно и то же определение интерфейса, реализованное с gsoap .На стороне сервера запускается mod_gsoap для Apache.Клиентская сторона - это написанная на заказ программа C ++ .Запуск одного потока на стороне клиента и нескольких рабочих на стороне Apache, он работает без проблем.Когда я запускаю более одного потока в клиенте, я получаю сообщения об ошибках для высоких нагрузок, например:

Error -1 fault in message exchange[no subcode] - "End of file or no input: message transfer interrupted" " or "SOAP 1.1 fault SOAP-ENV:Client[no subcode] - "Operation not permitted.

Если сообщается об ошибке, существует как минимум два запросакоторые терпят неудачу в то же время, так что это похоже на состояние гонки.Каждый клиентский поток создает свой собственный экземпляр Proxy.Поскольку я скомпилировал его с флагом is-Soap (-i), у каждого потока также должен быть свой экземпляр структуры мыла.

Я немного растерялся.Я проверил с Wireshark, что происходит.В нормальном случае между клиентом и сервером происходит сетевое рукопожатие, запрос публикуется, и апач отправляет обратно HTTP OK.Затем клиент инициирует отключение, рукопожатие - готово.В неработающих случаях я вижу физически новое соединение от клиента к серверу, идентифицированное новым портом на стороне клиента, которое не было установлено при рукопожатии.Первым действием является отправка FIN , ACK , сервер отправляет HTTP OK, в результате чего клиент отправляет RST (сброс).

1 Ответ

0 голосов
/ 27 августа 2018

После дополнительной проверки оказалось, что одна и та же структура мыла действительно использовалась более чем одним потоком. Таким образом, описанные симптомы - это разделение структуры мыла различными потоками.

Ошибка при создании потоков для объектов с использованием структур мыла:

vector<shared_ptr<Sender>> senders;
// create sender objects and fill senders

 for (auto s : senders) {
      auto thread_s=make_shared<thread>([&]{tl->run();});
      threads.push_back(thread_s);                                     
 }

Использование ссылки в лямбда-выражении приводит ко всем потокам, ссылающимся на один и тот же объект в конце.

...