首页 文章

我们是否需要为线程中的相同插槽添加锁定到Recv /发送/关闭代码

提问于
浏览
3

从像this这样的帖子中,我知道在linux上recv / send函数是线程安全的,允许用户同时从不同的线程在同一个套接字上操作 .

虽然这不是一个好的设计,但在以下情况下我想知道我们应该从用户级代码做什么来保持数据的一致性和 Health 的运行状态: There are threads operating on the same sockets, the first one for creating and closing socket, the second for reading socket and the last one for sending sockets. See the pseudo code

struct SocketInfo
 {
      int SockFd;
      int SockType;
      queue<Packet*> RecvPacks;
 };

 map<int, SocketInfo*> gSocketInfoMap;
 pthread_mutex_t       gSocketsLock;

 //Thread1
 pthread_mutex_lock(&gSocketsLock);
 // get information for sock
 SocketInfo* info = gSocketInfoMap[sock];
 pthread_mutex_unlock(&gSocketsLock);

 close(sock);         // line-1
 .....


 //thread-2
 pthread_mutex_lock(&gSocketsLock);
 SocketInfo* info = gSocketInfoMap[sock];
 pthread_mutex_unlock(&gSocketsLock);

 recv(sock, buffer, sizeof(buffer));         // line-2
 .....

 //thread-3
 pthread_mutex_lock(&gSocketsLock);
 SocketInfo* info = gSocketInfoMap[sock];
 pthread_mutex_unlock(&gSocketsLock);

 send(sock, buffer, sizeof buffer);         // line-3
 .....

我想知道是否需要将Line-1,Line-2和Line-3移动到gSocketsLock的保护范围内?为什么?

1 回答

  • 3

    正如链接问题所述,套接字操作是线程安全的 . 在任何情况下,接收和发送数据都是独立的操作,它们不会相互干扰 .

    显然,关闭一个主动读取和写入的套接字并不是一个好主意,但是将 close() 放在一个关键部分并不会阻止该bug . 无论什么机制确保活动套接字未关闭或未访问闭合套接字的级别高于OP中显示的关键部分 .

    如果一个线程关闭另一个线程试图用于I / O的套接字,则可能发生的最坏情况是recv / send调用将返回错误 .

    简而言之:不,将套接字操作放在关键部分中并不是一个好主意 . 它没有好处,并且不必要地增加了锁争用的可能性 .

相关问题