用于C ++的Win32 CRITICAL_SECTION的轻量级跨平台替代方案?

时间:2016-05-01 07:28:20

标签: c++ multithreading c++11 visual-c++ mutex

对于C ++,Win32 CRITICAL_SECTION是否有轻量级,跨平台的替代方案?我试图使我的Windows应用程序平台不可知,但std :: recursive_mutex比CRITICAL_SECTION慢。我目前正在使用Visual Studio 2013社区。

2 个答案:

答案 0 :(得分:1)

你应该看一下Boost.Thread库,特别是boost :: recursive_mutex。

(另见How do I make a critical section with Boost?

答案 1 :(得分:0)

http://en.cppreference.com/w/cpp/atomic/atomic_flag "可以使用atomic_flag"

在用户空间中实现自旋锁互斥锁

我调整了他们的用户空间spinlock mutex以允许递归锁定。

警告:速度编码的同步逻辑应该被认为是错误的,直到在一千次战斗中进行测试,并且还要仔细编码同步逻辑

#include <thread>
#include <vector>
#include <iostream>
#include <atomic>

std::atomic_flag lock = ATOMIC_FLAG_INIT;
std::thread::id current_thread;
volatile int counter;

void lockme()
{
    for(;;)
    {
        //protect access to current_thread and counter
        while (lock.test_and_set(std::memory_order_acquire))
        {}

        //use current_thread and counter

        //the thread with the conceptual lock is in current_thread
        //if that's this thread, or no such thread, make sure this thread has the lock and increment counter
        auto myid = std::this_thread::get_id();
        if(current_thread == myid || current_thread == std::thread::id())
        {
            counter++;
            current_thread = myid;
            lock.clear(std::memory_order_release);
            return;
        }

        lock.clear(std::memory_order_release);
    }
}

void unlockme()
{
    for(;;)
    {
        //protect access to current_thread and counter
        while (lock.test_and_set(std::memory_order_acquire))
        {}

        //use current_thread and counter

        //if this thread has the conceptual lock, perform the unlock
        //otherwise try again
        auto myid = std::this_thread::get_id();
        if(current_thread == myid)
        {
            counter--;
            if(counter==0)
                current_thread = std::thread::id();
            lock.clear(std::memory_order_release);
            return;
        }

        lock.clear(std::memory_order_release);
    }

}

void f(int n)
{
    for (int cnt = 0; cnt < 100; ++cnt) {
        for (int j = 0; j < 10; j++) lockme();
        std::cout << "Output from thread " << n << '\n';
        for (int j = 0; j < 10; j++) unlockme();
    }
}

int main()
{
    std::vector<std::thread> v;
    for (int n = 0; n < 10; ++n) {
        v.emplace_back(f, n);
    }
    for (auto& t : v) {
        t.join();
    }
}