我们可以在套接字映射上使用读写锁吗?

时间:2013-06-04 13:39:04

标签: c++ linux multithreading pthreads thread-synchronization

假设我们有std :: map套接字映射,它是一个多线程应用程序。在地图中有多个线程访问套接字用于发送套接字数据,同时只有一个线程访问地图中用于接收数据的套接字,如果远端关闭,该线程也将删除SocketInfo *。

在上面的情况下,我们可以使用读写锁(pthread_rwlock_t)来同步线程吗?如果是,我们是否比pthread_mutex_t有更多的好处?

史蒂夫

[PSEUDO CODE]

     class CSocketIO {  
         std::map<int, SocketInfo*> m_Sockets; //socket value and socket info
         pthread_t  m_ReadingSocketThreads;   // for reading socket data
     };

     class CSession {
         void SendOutNetworkPackets(); //access sockets for sending sock data
         pthread_t m_WorkerThread;     // do jobs and send sock data
     };

     class CSomeClass {
         void SendOutNetworkPackets(); // also access sockets
         pthread_t m_WorkerThread;     // do jobs and send sock data
     };

2 个答案:

答案 0 :(得分:0)

是的,您可以使用读/写锁来执行此操作,实际上建议这样做。

好处是你可以有多个同时读取器具有读/写锁定,而如果你使用一个简单的互斥锁,如果一个线程正在读取,其他想要读取的线程将阻塞,有效地序列化读取。通过读/写锁定,读取器只会在写入时阻塞。

答案 1 :(得分:0)

您不允许两个线程同时写入同一个套接字,对吧?您只想保护SocketInfo*

map的查找

读写器锁很少有益,而且往往有害。当我在多线程程序中有一个具有非确定性错误的客户端时,我寻找的第一个罪魁祸首是未正确使用的读写器锁。 (您只能使用读取器锁来保护真正const的函数调用。)

据推测,你的每个主题都是这样的:

// do some work to figure out what to send
SocketInfo* my_socket_info = 0;

// critical section begins here
pthread_mutex_lock(the_map_mutex);
socket_map_t::const_iterator i = m_Sockets.find(id);
if (i != m_Sockets.end()) {
  my_socket_info = i->second;
}
pthread_mutex_unlock(the_map_mutex);
// critical section is done

if (my_socket_info != 0) {
  // do a bunch of work to actually send the data
  // (including acquiring a mutex specific to the socket unless
  // you have some other way of guaranteeing that the socket isn't
  // currently being written by some other thread)

你需要问的第二个问题(在“我正在保护的const之后?”)是:the_map_mutex被锁定的时间百分比是多少?如果它低于约50%,那么你没有足够的争用使得读者 - 作者锁定获胜。通过测量单个线程在关键部分中花费的时间百分比,然后乘以系统上的硬件线程数,可以快速估计受the_map_mutex保护的关键部分的利用率。