perché concorrente
la concorrenza permette di sfruttare più core e ridurre la latenza. va gestita con disciplina.
misura prima di parallelizzare: più thread non sempre significa più performance.
thread base
usa std::thread per eseguire una funzione in parallelo.
#include <thread>
#include <iostream>
void job() {
std::cout << "task";
}
int main() {
std::thread t(job);
t.join();
}
mutex e lock
proteggi le risorse condivise con std::mutex e std::lock_guard.
#include <mutex>
std::mutex m;
int counter = 0;
void safe_inc() {
std::lock_guard<std::mutex> guard(m);
counter++;
}
async e future
std::async semplifica task asincroni con std::future.
#include <future>
int calc() { return 21 * 2; }
int main() {
auto fut = std::async(std::launch::async, calc);
int result = fut.get();
}
errori comuni
- dimenticare
join()odetach() - data race su variabili globali
- deadlock per ordine di lock sbagliato
- usare shared_ptr senza sincronizzazione
esercizi
crea un contatore thread-safe con std::atomic e confronta con il mutex.
implementa una coda di job con due thread consumer.
checklist
- usa lock_guard per lock sicuri
- preferisci async per task semplici
- evita state condiviso quando puoi
- scrivi test di concorrenza
panoramica
In questo capitolo su concorrenza e multithreading, thread, mutex e async in c++ moderno. L'obiettivo è trasformare i concetti in micro-pattern riutilizzabili con esempi piccoli e verificabili.
Lavora in sequenza: leggi, prova, modifica gli snippet e annota i trade-off principali (performance, leggibilità, manutenzione).
badge: concurrency advanced
obiettivi
- capire e applicare perché concorrente in uno scenario reale
- capire e applicare thread base in uno scenario reale
- capire e applicare mutex e lock in uno scenario reale
- capire e applicare async e future in uno scenario reale
scheda rapida
#include <iostream>
#include <vector>
int main() {
std::vector<int> dati{1, 2, 3};
for (auto &v : dati) {
v *= 2;
}
for (const auto &v : dati) {
std::cout << v << " ";
}
std::cout << "\n";
return 0;
}
Adatta questo scheletro agli esempi della lezione e sostituisci i dati con il tuo dominio.
tips
- compila con warning elevati
- preferisci RAII
- usa const ovunque possibile
- usa condition_variable per sincronizzazione
- preferisci future per risultati
- gestisci shutdown pulito
tip: La sincronizzazione esplicita vale più di mille spin loop.
mini progetto
Queue producer/consumer con condition_variable.
- implementa coda protetta
- crea producer e consumer
- notifica con condition_variable
- gestisci stop
output atteso: uno script o query ripetibile con risultati verificabili.