• 6303阅读
  • 4回复

请求帮助,stl的map问题(多线操作map问题) [复制链接]

上一主题 下一主题
离线fangjuntan
 

只看楼主 倒序阅读 楼主  发表于: 2009-11-19
我定义了一个map<string, list<string> > hash_data;
有两个线程要线程要对hash_data进行操作,其中一个是插入操作,一个是删除操作。

线程一:
map<string, list<string> >::iterator it = hash_data.find(key);
if (it == hash_data.end())
{
pthread_mutex_lock(&hash_mutex);
     //新节点插入。
pthread_mutex_unlock(&hash_mutex);
}
else
{

    string datatmp;
    datatmp.append(data, data_len);

    pthread_mutex_lock(&hash_mutex);
    it->second.push_back(datatmp);
    pthread_mutex_unlock(&hash_mutex);
}

线程二:
map<string, list<string> >::iterator it_data;
for (it_data = hash_data.begin(); it_data != hash_data.end();)
{
//一些数据操作,判断是否删除等。

  pthread_mutex_lock(&hash_mutex);
  hash_status.erase(it_data->first);
  it_data->second.clear();
  hash_data.erase(it_data++);
  pthread_mutex_unlock(&hash_mutex);
}


以上线程在工作的时候会出现异常.

我不想对线程一加一个大锁,如下:

pthread_mutex_lock(&hash_mutex);
map<string, list<string> >::iterator it = hash_data.find(key);
if (it == hash_data.end())
{

     //新节点插入。

}
else
{

    string datatmp;
    datatmp.append(data, data_len);

    it->second.push_back(datatmp);

}
    pthread_mutex_unlock(&hash_mutex);


因为这样会效率很低。



大家有什么高招没有,指点一下,谢谢大虾。
离线蛮蛮
只看该作者 1楼 发表于: 2009-11-20
你这个异常似乎不是进程的问题,而是erase函数的问题,在erase之后it_data的位置会自动指向下一个位置,如果你的erase到了end,你的it_data再++就超出范围了,再调用就会出异常了.相信你能解决你的问题
蛮蛮工作室
离线fangjuntan

只看该作者 2楼 发表于: 2009-11-21
引用第1楼蛮蛮于2009-11-20 10:05发表的  :
你这个异常似乎不是进程的问题,而是erase函数的问题,在erase之后it_data的位置会自动指向下一个位置,如果你的erase到了end,你的it_data再++就超出范围了,再调用就会出异常了.相信你能解决你的问题

谢谢!
主要是互斥的问题。想换种方式实现。
离线318065268
只看该作者 3楼 发表于: 2009-11-26
看到这个题目内容,忽然想起数据库操作中的submit。可以采取类似的操作,我们不直接操作共享数据,而只是向这个共享数据提出一些操作请求,然后再使用一些代码专门控制对这些请求的执行。

于是可以分给插入操作一个或多个缓冲的map<string, list<string> > tmpInsertData; 给删除操作一个或多个缓冲的map<string, list<string> > tmpDeleteData;完成提交之后,可以发送信号给我们的处理函数。
此外,还需要一个关键性的枚举变量,比如key,可以取Key::InsertSubmitted,Key::DeleteSubmitted,或者两个属性的叠加。
这样的话我们就可以减少对共享数据的加锁和解锁为只对key做一个加锁解锁操作即可。我们的处理函数在接收到来自线程的要求处理递交的请求的信号后,就开始查询key的状态,根据状态的内容,开始读取对应的缓冲数据,然后操作主体的map。

当然,在操作缓存的map时也需要做加锁控制,因为主线程需要读取。不过毕竟比全部遍历操作加锁要少了很多。

线程操作很复杂,不知道这个想的是否周全,恳请看到帖子的指正一二。
Email  rsail@126.com(私人邮箱)
QQ:   318065268
离线fangjuntan

只看该作者 4楼 发表于: 2009-11-29
回 3楼(318065268) 的帖子
谢谢!
查询key的状态应该也耗时吧,查完key的状态后,还需要去查询缓冲中的map,需要两次查询map?
快速回复
限100 字节
 
上一个 下一个