C++ 我们是否需要为线程之间的同一套接字的Recv/Send/Close代码添加锁

C++ 我们是否需要为线程之间的同一套接字的Recv/Send/Close代码添加锁,c++,linux,multithreading,sockets,C++,Linux,Multithreading,Sockets,从类似的帖子中,我知道linux上的recv/send函数是线程安全的,用户可以同时从不同的线程在同一个套接字上操作 虽然这不是一个好的设计,但在以下情况下,我想知道我们应该从用户级代码中做些什么来保持数据一致性和健康的运行状态:有线程在同一个套接字上运行,第一个用于创建和关闭套接字,第二个用于读取套接字,最后一个用于发送套接字。请参阅伪代码 struct SocketInfo { int SockFd; int SockType; queue<Pa

从类似的帖子中,我知道linux上的recv/send函数是线程安全的,用户可以同时从不同的线程在同一个套接字上操作

虽然这不是一个好的设计,但在以下情况下,我想知道我们应该从用户级代码中做些什么来保持数据一致性和健康的运行状态:有线程在同一个套接字上运行,第一个用于创建和关闭套接字,第二个用于读取套接字,最后一个用于发送套接字。请参阅伪代码

 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
 .....
struct SocketInfo
{
int-SockFd;
int型;
队列RecvPacks;
};
地图gSocketInfoMap;
pthread_mutex_t gSocketsLock;
//螺纹1
pthread_mutex_lock(&gSocketsLock);
//获取有关sock的信息
SocketInfo*info=gsSocketinfomap[sock];
pthread_mutex_unlock(&gSocketsLock);
关上(袜子);//第1行
.....
//螺纹-2
pthread_mutex_lock(&gSocketsLock);
SocketInfo*info=gsSocketinfomap[sock];
pthread_mutex_unlock(&gSocketsLock);
recv(sock,buffer,sizeof(buffer));//第2行
.....
//螺纹-3
pthread_mutex_lock(&gSocketsLock);
SocketInfo*info=gsSocketinfomap[sock];
pthread_mutex_unlock(&gSocketsLock);
发送(sock、buffer、sizeof buffer);//第3行
.....

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

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

显然,关闭一个正在读写的套接字不是一个好主意,但是将
close()
放在一个关键部分内并不能防止该错误。任何确保活动插座未关闭或未访问已关闭插座的机制的级别都高于OP中所示的关键部分

如果一个线程关闭另一个线程试图用于I/O的套接字,最糟糕的情况是recv/send调用将返回错误

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