Многопоточность - отключение TCP-соединения - PullRequest
0 голосов
/ 04 декабря 2010

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

Здесь переключение происходит в строке 5 между потоками без фактического завершения вызова разъединения.

void Disconnect() {
    if(isConnected) {
        if (closesocket(sockClient) != SOCKET_ERROR) {
            isConnected = false;
        }
    }
}

Как я должен избегать переключателей и изящно позволить ему завершить вызов разъединения?

1 Ответ

1 голос
/ 04 декабря 2010

Вот два возможных решения.

Вы можете изолировать ВСЕ доступ к сокету в потоке сокета (неосновном), и вместо того, чтобы отсоединить сокет от первичного потока, пусть этот поток сигнализирует неосновныйПоток, который отключается (или какое-то другое действие), необходим.Это потребует от вашего вторичного потока ожидания двух объектов - сокета и сигнализатора (скажем, Win32 Event ), который указывает на необходимость отключения.

Если, с другой стороны, вы хотитечтобы позволить первичному потоку отключиться (как вы это делаете сейчас), вам необходимо проверить весь ваш код, использующий сокет, и сделать его поточно-ориентированным, используя средства защиты от блокировки, чтобы предотвратить одновременный доступ к сокету и связанным данным состояния. Boost.Thread имеет подходящие блокировки, которые вы можете использовать здесь, в противном случае вы можете реализовать свою собственную как оболочку для чего-то вроде Win32 CriticalSection .

Вторым будет мое предпочтительное решение - тот факт, что вы задаете этот вопрос, означает, что вам все равно нужно вернуться и подумать о безопасности потоков в своем проекте.Даже если вы придерживаетесь первой идеи, изложенной выше, вам все равно, вероятно, потребуется поддерживать состояние, чтобы избежать нескольких сигналов разъединения, отправляемых из основного потока, и это должно быть защищено блокировкой.Также, если вы хотите, чтобы неосновной поток обрабатывал входящие события, отличные от «разъединения», между потоками должно было бы быть связано состояние, которым нужно будет управлять.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...