Я хотел знать, есть ли у boost какие-либо библиотеки, которые помогают в реализации спиновых замков. Я знаю, что boost поддерживает мьютексы, но я не мог найти примеров, которые показывают или описывают spinlocks в boost. Будут оценены примеры, показывающие, как реализовать прямую блокировку с использованием boost (предпочтительно). (C++ 98)Реализация спин-блокировки в Boost. Необходимый пример:
2
A
ответ
0
образец с использованием C++, 11 атомарный:
#include <atomic>
typedef std::atomic<bool> Lock;
void enterCritical(Lock& lock) {
bool unlocked = false;
while (!lock.compare_exchange_weak(unlocked, true));
}
void exitCritical(Lock& lock) {
lock.store(false);
}
3
Пример использования Boost.Atomic
:
#include <boost/atomic.hpp>
class SpinLock
{
boost::atomic_flag flag; // it differs from std::atomic_flag a bit -
// does not require ATOMIC_FLAG_INIT
public:
void lock()
{
while(flag.test_and_set(boost::memory_order_acquire))
;
}
bool try_lock()
{
return !flag.test_and_set(boost::memory_order_acquire);
}
void unlock()
{
flag.clear(boost::memory_order_release);
}
};
#include <boost/range/algorithm.hpp>
#include <boost/atomic.hpp>
#include <boost/thread.hpp>
#include <iostream>
#include <vector>
class SpinLock
{
boost::atomic_flag flag;
public:
void lock()
{
while(flag.test_and_set(boost::memory_order_acquire))
;
}
bool try_lock()
{
return !flag.test_and_set(boost::memory_order_acquire);
}
void unlock()
{
flag.clear(boost::memory_order_release);
}
};
int main()
{
using namespace std; using namespace boost;
SpinLock lock;
vector<thread> v;
for(auto i = 0; i!=4; ++i)
v.emplace_back([&lock, i]
{
for(auto j = 0; j!=16; ++j)
{
this_thread::yield();
lock_guard<SpinLock> x(lock);
cout << "Hello from " << i << flush << "\tj = " << j << endl;
}
});
for(auto &t: v)
t.join();
}
Выход:
Hello from 0 j = 0
Hello from 1 j = 0
Hello from 3 j = 0
Hello from 2 j = 0
Hello from 3 j = 1
Hello from 1 j = 1
Hello from 3 j = 2
Hello from 2 j = 1
Hello from 1 j = 2
Hello from 2 j = 2
Hello from 1 j = 3
Hello from 2 j = 3
Hello from 1 j = 4
Hello from 3 j = 3
Hello from 2 j = 4
Hello from 1 j = 5
Hello from 2 j = 5
Hello from 1 j = 6
Hello from 2 j = 6
Hello from 1 j = 7
Hello from 2 j = 7
Hello from 1 j = 8
Hello from 2 j = 8
Hello from 3 j = 4
Hello from 2 j = 9
Hello from 3 j = 5
Hello from 1 j = 9
Hello from 2 j = 10
Hello from 1 j = 10
Hello from 2 j = 11
Hello from 3 j = 6
Hello from 1 j = 11
Hello from 2 j = 12
Hello from 3 j = 7
Hello from 1 j = 12
Hello from 2 j = 13
Hello from 3 j = 8
Hello from 2 j = 14
Hello from 3 j = 9
Hello from 1 j = 13
Hello from 2 j = 15
Hello from 1 j = 14
Hello from 3 j = 10
Hello from 1 j = 15
Hello from 3 j = 11
Hello from 3 j = 12
Hello from 3 j = 13
Hello from 3 j = 14
Hello from 3 j = 15
Hello from 0 j = 1
Hello from 0 j = 2
Hello from 0 j = 3
Hello from 0 j = 4
Hello from 0 j = 5
Hello from 0 j = 6
Hello from 0 j = 7
Hello from 0 j = 8
Hello from 0 j = 9
Hello from 0 j = 10
Hello from 0 j = 11
Hello from 0 j = 12
Hello from 0 j = 13
Hello from 0 j = 14
Hello from 0 j = 15
0
The spinlock solution provided by erenon sometimes generated crumble cout result. but the boost::mutext solution won't. So either the solution is incorrect, or my understanding of cout is wrong.
#include <iostream>
#include <thread>
#include <atomic>
#include <boost/thread/mutex.hpp>
using namespace std;
class spinlock {
private:
std::atomic<bool> lock_;
public:
spinlock() {
lock_.store(false);
}
void lock() {
bool unlocked = false;
while (!lock_.compare_exchange_weak(unlocked, true));
}
void unlock() {
lock_.store(false);
}
};
class add_one
{
private:
std::string name_;
unsigned int& num_;
spinlock & lock_;
boost::mutex & mutex_;
public:
add_one(std::string name, unsigned int& num, spinlock &lock, boost::mutex &mutex)
:name_(name),
num_(num),
lock_(lock),
mutex_(mutex)
{
}
void add_and_display()
{
while(true)
{
lock_.lock();
//boost::lock_guard<boost::mutex> g(mutex_);
std::cout << name_ << " " << num_ << endl;
if(num_ == 10000000)
{
return;
}
num_++;
lock_.unlock();
}
}
};
int main()
{
cout << "Hello World" << endl;
unsigned int n = 0;
spinlock lock;
boost::mutex mutex;
add_one one("t1", n ,lock, mutex);
add_one two("t2", n ,lock, mutex);
add_one three("t3", n ,lock, mutex);
//add_one four("t4", n ,lock, mutex);
std::thread t1(std::bind(&add_one::add_and_display, one));
std::thread t2(std::bind(&add_one::add_and_display, two));
std::thread t3(std::bind(&add_one::add_and_display, three));
//std::thread t4(std::bind(&add_one::add_and_display, four));
t1.join();
t2.join();
t3.join();
//t4.join();
return 0;
}
Смежные вопросы
- 1. threejs AnimationClip Необходимый пример
- 2. Необходимый пример Greendroid GDExpandableListActivity
- 3. Пример/пример, необходимый для настройки таблицы/поля
- 4. Необходимый пример приложения приложения JavaFX
- 5. Необходимый пример Excel SheetSelectionChange. C++
- 6. Необходимый пример короткой записи WebStorm
- 7. QNetworkAccessManager Необходимый пример запроса PUT
- 8. odata v4 Необходимый пример поиска
- 9. Функциональный пример OpenGL, необходимый в Android
- 10. Необходимый пример использования Promise в node.js
- 11. Boost memory_order_consume Пример
- 12. Boost Ping Пример
- 13. Rcpp boost :: dynamic_bitset реализация
- 14. Boost ASIO IO_SERVICE Реализация?
- 15. boost :: is_nothrow_move_constructible реализация
- 16. Реализация SSML в Alexa Пример
- 17. Простой пример, необходимый для тестирования установки
- 18. Редукционная муфта простой пример, необходимый для начинающего
- 19. Необходимый пример клиента Java/Scala SAML
- 20. реализация javascript Пример CORS
- 21. Javascript-код, необходимый для объяснения (пример рекурсии)
- 22. Необходимая функция длины слова Python Необходимый пример
- 23. Весна 3 Необходимый пример интеграции JSF 2
- 24. Реализация «NOT» в boost :: spirit mini_c
- 25. Конкретный пример boost :: serialization :: traits?
- 26. Boost :: Пример простой грамматики духа
- 27. Попросите пример ограничения boost :: bind()
- 28. boost :: algorithm :: boyer_moore_search Пример OO
- 29. boost пример не удалось построить
- 30. Boost ASIO пример не строится
1. Лучше использовать 'зЬй :: atomic_flag' для этой цели, потому что он гарантированно безблокировочного. 2. Существует библиотека 'Boost.Atomic', которая также имеет' boost :: atomic_flag'. –
Однако интерфейс atom_flag отличается: http://en.cppreference.com/w/cpp/atomic/atomic_flag -> вы не можете использовать сравнение и обмен, проверяйте и устанавливайте. – erenon
re2: Зачем использовать Boost, если есть эквивалент STL? (Предполагая, что C++ 11) – erenon