当前位置:  开发笔记 > 编程语言 > 正文

如何在C++中使用任意字符串作为锁?

如何解决《如何在C++中使用任意字符串作为锁?》经验,为你挑选了1个好方法。

假设我有一个多线程C++程序,它以函数调用的形式处理请求handleRequest(string key).每次调用都handleRequest发生在一个单独的线程中,并且存在任意大量的可能值key.

我想要以下行为:

同时调用handleRequest(key)在具有相同值时被序列化key.

全局序列化最小化.

handleRequest可能的主体看起来像这样:

void handleRequest(string key) {
    KeyLock lock(key);
    // Handle the request.
}

问题:如何实现KeyLock以获得所需的行为?

一个天真的实现可能会像这样开始:

KeyLock::KeyLock(string key) {
    global_lock->Lock();
    internal_lock_ = global_key_map[key];
    if (internal_lock_  == NULL) {
        internal_lock_  = new Lock();
        global_key_map[key] = internal_lock_;
    }
    global_lock->Unlock();
    internal_lock_->Lock();
}

KeyLock::~KeyLock() {
    internal_lock_->Unlock();
    // Remove internal_lock_ from global_key_map iff no other threads are waiting for it.
}

...但是,这需要在每个请求的开头和结尾处进行全局锁定,并为每个请求创建单独的Lock对象.如果调用之间的争用很高handleRequest,那可能不是问题,但如果争用率很低,则可能会产生大量开销.



1> Michael Burr..:

您可以执行与您的问题类似的操作,但不是单个global_key_map有多个(可能在数组或向量中) - 使用哪一个是由字符串上的一些简单哈希函数确定的.

通过这种方式而不是单个全局锁定,您可以将其分散到几个独立的锁定中.

这是一种常用于内存分配器的模式(我不知道模式是否有名称 - 它应该).当一个请求进来时,某些东西决定了分配将来自哪个池(通常是请求的大小,但其他参数也可以考虑因素),那么只需要锁定该池.如果分配请求来自将使用不同池的另一个线程,则没有锁争用.

推荐阅读
yzh148448
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有