Читая этот спинлок и другие многозадачные вещи, я столкнулся с этим кодом:
#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();
}
Не могли бы вы объяснить, почему для имеет только один параметр?
И что делает этот оператор двоеточия?
И что это за объект?
Это на основе диапазона для.
t
имеет тип std::thread&
,
Это основано на диапазоне для цикла. Они были введены с C ++ 11. Вы перебираете контейнер.
Его синтаксис:
for ( range_declaration : range_expression ) loop_statement
Цикл for выполняется от начала контейнера до конца.
Пример:
int an_array[]={1,2,3,5,6,56,34,65,3,234};
for(int a : an_array)
cout << a;
этот for
цикл эквивалентен:
for(int index = 0; index < sizeof(an_array) / sizeof(an_array[0]) /*10*/; ++index)
cout << an_array[index];
Поддерживающие компиляторы понимают, что vector
есть, если используется против диапазона на основе for
цикл, и они называют begin
а также end
для контейнера. Следовательно, последний цикл такой же как:
for(vector<thread>::itereator t = v.begin(); t != v.end(); ++t)
t->join(); // Or. (*t).join()
основанный на диапазоне цикл for, вам не нужно знать размер, это означает, что все t в контейнере v делают что-то (присоединение в этом случае). несколько отличается от традиционного для цикла