Sono confuso circa il funzionamento atomica su C++ 11,C++ 11 quando incrementa la variabile atomica e la assegna ad un altro valore, è un'operazione atomica?
So che il atomica sé incremento variabile è un'operazione atomica,
ma io uso il compito di altro valore, solo dubitarne.
il codice, proprio come:
//....
static std::atomic<int> i; // global variable
//....
// in the thread
int id = ++i;
quando si utilizza l'assegnazione a diversi thread, è il valore unico id?
il codice di prova:
#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;
}
ci sono tre fili,
Una classe di utilizzo lock_guard mantengono unico.
classe B basta usare operazione atomica, e assegnare alla variabile
Vedere l'API 'std :: atomic :: fetch_add' che copre le due operazioni in un'unità atomica. –
Un'assegnazione a una variabile atomica (o un'operazione di incremento) è, beh, atomica. Non è garantito che l'assegnazione a qualsiasi altra variabile sia atomica. Tuttavia, l'atomicità da sola non è sufficiente in tutti gli scenari con accesso concorrente per renderla "thread-safe". Inoltre, osservando il codice in classe 'B', sembra che si desideri rendere la variabile membro id' atomgenerator', invece la variabile membro 'id_'. – CouchDeveloper
sto leggendo il codice crtmpserver, e ogni connessione con la sua unica classe iohandler, l'id del gestore personale è generata dal generatore statico. crtmpserver è Single Process, se provo ad aggiungere il supporto multithread, l'id dovrebbe rimanere unico come prima –