2016-05-01 21 views
-1

C++のWin32 CRITICAL_SECTIONに代わる、軽量でクロスプラットフォームの代替品はありますか?私は、私のWindowsアプリケーションプラットフォームには無関係なものにしようとしていますが、std :: recursive_mutexはCRITICAL_SECTIONよりも遅いです。私は現在、Visual Studio 2013 Communityを使用しています。C++のWin32 CRITICAL_SECTIONに対する軽量なクロスプラットフォームの代替案

+0

それは再帰的ではありませんので、残念ながら、私は 'のstd :: mutex'を使用することはできません。さらに、 'std :: mutex'は' std :: recursive_mutex'と同じくらい遅いです。 – meriken2ch

+1

あなたはstd :: atomicを調べるべきです – zeromus

+0

'std :: atomic'を試しましたが、奇妙なBEX/BEX64例外があります。あなたが私にいくつかのコードを表示することができれば嬉しいです – meriken2ch

答えて

1

具体的には、Boost.Threadライブラリとboost :: recursive_mutexを見てください。

(またHow do I make a critical section with Boost?参照)

+0

ナットを裂くためにスレッジハンマーを使用するような気がしますが、なぜそうしないのでしょうか...わかります。 – meriken2ch

+0

あなたの実際のニーズに応じて、より軽量の代替品ももちろんご利用いただけます。共有リソースを保護する必要がある場合は、[boost :: atomic](http://www.boost.org/doc/libs/1_59_0/doc/html/atomic/usage_examples.html)(またはstd :: atomic if C++ 11の機能を使用することもできます)もオプションになる可能性があります。 – Florian

+1

[boost :: detail :: lightweight_mutex](http://www.boost.org/doc/libs/1_60_0/boost/detail/lightweight_mutex.hpp)は、おそらくあなたが探しているものです。ミューテックスのコンセプトの必要条件は、WindowsではCRITICAL_SECTION、POSIXシステムではpthread_mutexにマッピングされます。 – Florian

0

http://en.cppreference.com/w/cpp/atomic/atomic_flag 「スピンロックミューテックスはatomic_flagを使用してユーザ空間で実行することができる」

Iは、再帰的ロックを可能にするために、それらのユーザ空間スピンロックミューテックスを適合。

警告:千戦いで試験するまでspeedcoded同期ロジックが故障を想定しなければならない、とも慎重にコード化された同期ロジック

#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(); 
    } 
} 
関連する問題