Boost Thread умирает до окончания работы - PullRequest
2 голосов
/ 26 марта 2011

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

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

Однако, таким образом, поток умирает с концом выполнения кода конструктора. Я думаю, я не понимаю, как работают Boost / Posix темы. Я пришел из фона Java.

server::server(int port) {

try {
    boost::asio::io_service io_service;
    tcp_server server(io_service, port);
    boost::thread t(boost::bind(&boost::asio::io_service::run, &io_service));
} catch (std::exception& e) {
    std::cerr << e.what() << std::endl;
}

Ответы [ 2 ]

5 голосов
/ 26 марта 2011

Вы создаете локальную переменную io_service, которую вы передаете рабочей функции вашего нового потока. Когда переменная выходит из области видимости (конструктор завершает работу), io_service уничтожается и больше не может быть доступен.

Однако рабочая функция вашего потока не знает этого и, вероятно, пытается снова получить доступ к остаткам этого объекта. Уродство наступает.

Ошибка не связана с потоками, но является экземпляром распространенного типа ошибки, называемой ", возвращающей адрес локального " (даже если вы на самом деле не возвращаете ее здесь, механизм то же самое).

Решением было бы продлить срок жизни объекта io_service, либо с помощью ручного управления (new / delete), либо путем его увеличения (например, сделав его членом класса на server вместо локальный внутри конструктора).

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

0 голосов
/ 26 марта 2011

Ваш io_service должен быть заполнен некоторыми io_service::work, чтобы сделать, либо явно, либо из вашего tcp_server объекта. В противном случае io_service::run () немедленно вернет управление. Изучите примеры asio , это понятие важно понять.

Рабочий класс используется для информирования io_service, когда начинается работа и отделки. Это гарантирует, что Функция run () объекта io_service не выйдет, пока идет работа, и что он выходит, когда нет осталась незаконченная работа.

Рабочий класс является копируемым так что это может быть использовано в качестве данных член в классе обработчика. Это не переуступка.

Я подозреваю, что ваш код является надуманным примером, скорее всего, ему не нужен поток для запуска io_service. Основной поток будет хорошо.

...