аз съм объркан за атомната операция на C ++ 11,
Знам, че атомната променлива самостоятелно нарастване е атомна операция,
но аз използвам заданието на друга стойност, просто се съмнявам в него.
кодът точно като:
//....
static std::atomic<int> i; // global variable
//....
// in the thread
int id = ++i;
когато използвате заданието на различни нишки, е id уникалната стойност?
кода на изпитването:
#include <thread>
#include <mutex>
#include <atomic>
#include <iostream>
class A {
public:
static int idGenerator;
static std::mutex m;
A () {
// i know this operation will keep the id_ is unique
std::lock_guard<std::mutex> lock(m);
id_ = ++idGenerator;
}
void F(std::string name) {
std::cout << name << " " << id_ << std::endl;
}
private:
int id_;
};
int A::idGenerator = 0;
std::mutex A::m;
class B {
public:
static int idGenerator;
B () {
// after self increment, is the assignment atomic?
id_ = (++idGenerator);
}
void F(std::string name) {
std::cout << name << " " << id_.load() << std::endl;
}
private:
std::atomic<int> id_;
};
int B::idGenerator = 0;
void funcA() {
A a2;
a2.F("a2");
}
void funcB() {
B b2;
b2.F("b2");
}
int main() {
A a1;
B b1;
std::thread t1(&funcA);
std::thread t2(&funcB);
a1.F("a1");
b1.F("b1");
t1.join();
t2.join();
return 0;
}
има три нишки,
Класът, използващ lock_guard, запазва уникален характер.
Б клас просто използва атомна операция, и присвояване на променливата
Отговори:
8 за отговор № 1Спецификацията на функциите за атомно увеличение дава решаваща представа за тяхното поведение - от http://en.cppreference.com/w/cpp/atomic/atomic/operator_arith за Интеграл T
типа:
T operator++();
T operator++() volatile;
T operator++( int );
T operator++( int ) volatile;
Забележете, че връщат T
по стойност и никога не връща обичайното T&
от предварително увеличение. Поради тази причина "четенето" на пост-увеличената стойност не е втора отделна операция и е част от самата операция за атомно увеличение.
Вижте също текста "Връщана стойност" и "Забележка" на горепосочената страница.
2 за отговор № 2
static std::atomic<int> i; // global variable
// in the thread
int id = ++i;
когато използвате заданието на различни нишки, е id уникалната стойност?
Да. C ++ атомните променливи гарантират това ++i
ще бъдат оценени атомно, така че всяка стойност от id
върху различни нишки са уникални.
Изразът id = ++i;
се изпълнява следните стъпки.
- атомно увеличение
i
, и под-израз (++i
) се оценява след добавената стойност. - задайте "оценена стойност" на
id
, (тази стъпка не е атомно)
0 за отговор № 3
kaka_ace,
За съжаление в случая, който сте предоставили, той не е атомен.
Тук е причината, поради която операцията преди увеличението е атомна, погледнете генерирания комплект:
add %l0,1,%l0
(може да варира малко в зависимост от използвания монтаж)
Но това е операция.Това е защо тя е атомна.
Когато прехвърляте предварителна стъпка на местна променлива, това е най-малко две инструкции:
add %l0,1,%l0
st l0, [%fp-4]
Това генерира най-малко две инструкции и следователно вече не е атомна.
Моля, уведомете ни, ако имате въпроси!