对于简短的共享操作和几个独特的操作,是否存在共享互斥的任何方法?

时间:2016-10-27 11:06:31

标签: c++ multithreading c++11 concurrency mutex

众所周知$(function () { $("#filter").click(function () { try { ids = $("#inputFilter").val(); if (ids != "") { idsArray = ids.split(","); $("#my-table tr:gt(0)").hide(); $.each(idsArray, function (i, v) { $("#my-table tr[data-id=" + v + "]").show(); }) } else { $("#my-table tr").show(); } } catch (error) { try { $body.removeClass("loading"); } catch (error) { } alert(error); } }); }); (C ++ 14)和std::shared_timed_mutex(C ++ 17)的性能优势仅超过std::shared_mutex 非常长 std::mutex s(读取操作),std::shared_lock超过std::shared_lock s时。

但即使大多数都是读取操作,并且它们很短,那么std::unique_lock会更快 - 这就是为什么在C ++ 11标准std::mutexstd::shared_mutex中不包括在内。

是否存在某种共享互斥锁的任何方法或实现,如果读取不仅仅是更多,那么它具有超过std::shared_timed_mutex的性能优势,对于短操作也 ,并且还有更多如下?

std::mutex / std::unique_lock = 1/1 000 000 000 000

对于短的共享操作和几个独特的操作,是否存在共享互斥的方法?

1 个答案:

答案 0 :(得分:0)

可能的方法可能是使用重复数据。这应该与大量的读者和只有少数作家很好地扩展。我不知道它是否比shared_mutex()更快,但是是另一种选择

基本理念:

每个读者都可以使用阅读器副本,而作者可以修改单独的编写者副本。要提交更改,请将writer-object存储在新的reader-object中,该reader-object将从每个新读取器中获取。下一个提交将存储到现在的旧读者对象中。因此,作者需要等待,直到所有旧读者都释放对这个对象的锁定。

简单的例子:

struct data{
    int a;
};

struct secured_data {
    data read[2];
    data write;
    std::atomic<int> current = 0;
    std::atomic<int> num_read[2] = 0;

    std::mutex m;

    data* read_lock() {
        // increase reader-counter of current data-object
        int c = current.load();
        num_read[c].fetch_add(1);
        // return current copy
        return &read + c;
    }

    void read_unlock(data* old) {
        // decrease the old data-object (which was returned by read_lock())
        num_read[old - &read].fetch_sub(1);


    }

    data* lock() {
        m.lock();
        // every modification happens on a seperate copy
        write = read[current.load()];
        return &write;
    }

    void unlock() {
       int c;
       // wait until all readers using an old copy have released their lock
       do {
           c = current.load();
       } while (num_read[(c + 1) % 2].load() != 0);
       // copy into new read-object
       read[(c + 1) % 2] = write;
       // swap read-object
       // all readers now use an old version
       current.store((c + 1) % 2);
       m.unlock();
    }
}