如何在不同的线程中处理相同的套接字?

时间:2009-10-06 06:32:06

标签: c++ multithreading exception sockets

我正在尝试在不同的线程中处理socket,从而导致运行时失败。请参阅以下代码。

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()时会产生异常。

我用Google搜索了这个错误并得到了一些理由。 这是因为; CSocket对象只能在单个线程的上下文中使用,因为CAsyncSocket对象封装的SOCKET句柄存储在每个线程的句柄映射中。他们还通过在线程(http://support.microsoft.com/kb/175668)之间共享SOCKET句柄来建议解决方案。但是这在我的情况下是不可能的,因为我除了一些通知回调,这不适用于上述解决方案。任何人都可以建议一种在不影响通知回调的情况下在线程之间共享CSocket的机制吗?

3 个答案:

答案 0 :(得分:3)

您可以直接使用套接字并停止使用显然有缺陷的MFC实现......

答案 1 :(得分:1)

我建议你使用像Boost.Asio这样的更高级别(和更少错误的)套接字API。请注意,无论如何它都不会使套接字成为线程安全的(参见there)。你必须使用一些锁定/解锁设施。

我不确定我是否理解您在不使用通知回调的情况下在线程间共享套接字的问题。在线程T1和T2之间,假设T1管理套接字,T2只有两种方式来了解套接字事件。 T1发出的一些通知或T2发送给T1的问题,无论是定期还是阻止通话。

答案 2 :(得分:1)

如果你说,“CSocket对象只应在单个线程的上下文中使用”,那么就没有“在线程之间共享CSocket的机制”。

换句话说,其中一个线程需要拥有CSocket,其他线程不能搞乱它。

在这种情况下,解决方案是使用线程间消息传递系统。这样,其他线程之一就可以向所有者发送消息说:“嘿,伙计,关闭你的插座!”

有关如何进行此消息传递的详细信息完全取决于程序的上下文。