Как обрабатывать один и тот же сокет в разных потоках? - PullRequest
0 голосов
/ 06 октября 2009

Я пытаюсь обработать сокет в разных потоках, создавая сбой во время выполнения. См. Следующий код.

void MySocket::Lock()
{
    m_LockCount++;

    if( m_LockCount )
    {
        CSocket::Create( 8080 );
    }
}

void MySocket::Unlock()
{
    m_LockCount--;

    if( !m_LockCount )
    {
        CSocket::Close();
    }
}

Я вызываю Lock () из одного потока и Unlock () из другого. Когда он выполняет CSocket :: Close (), он выдает исключение.

Я погуглил эту ошибку и получил несколько причин. Это происходит потому, что; объект CSocket должен использоваться только в контексте одного потока, потому что дескриптор SOCKET, инкапсулированный объектом CAsyncSocket, хранится в карте дескрипторов для каждого потока. Они также предлагают решение путем совместного использования дескрипторов SOCKET между потоками (http://support.microsoft.com/kb/175668). Но в моем случае это невозможно, так как я исключаю некоторый обратный вызов уведомлений, который не будет работать с вышеуказанным решением. Кто-нибудь может предложить механизм для совместного использования CSocket? среди потоков без выполнения обратных вызовов уведомлений?

Ответы [ 3 ]

3 голосов
/ 06 октября 2009

Вы могли бы просто использовать сокет напрямую и прекратить использовать, очевидно, некорректную реализацию MFC ...

1 голос
/ 06 октября 2009

Если, как вы говорите, «объект CSocket должен использоваться только в контексте одного потока», то нет «механизма для совместного использования CSocket между потоками».

Другими словами, один из потоков должен владеть CSocket, а другие не могут связываться с ним.

В таких случаях решение заключается в использовании системы обмена сообщениями между потоками. Таким образом, один из других потоков может отправить владельцу сообщение: «Эй, приятель, закрой свой сокет!»

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

1 голос
/ 06 октября 2009

Я бы посоветовал вам использовать более высокоуровневый (и менее глючный) API сокетов, например Boost.Asio . Обратите внимание, что это не делает сокеты потокобезопасными в любом случае (см. там ). Вы должны использовать некоторые средства блокировки / разблокировки.

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

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