Introducció al Multifil
El multifil (multithreading) és una tècnica de programació que permet executar múltiples fils (threads) de manera concurrent dins d'un mateix procés. Això pot millorar significativament el rendiment d'una aplicació, especialment en sistemes amb múltiples nuclis de CPU.
Conceptes Clau
- Fil (Thread): Un fil és la unitat més petita d'execució que pot ser gestionada pel sistema operatiu.
- Procés: Un procés és un programa en execució que pot contenir múltiples fils.
- Concurrència: La capacitat d'executar múltiples tasques al mateix temps.
- Paral·lelisme: L'execució simultània de múltiples tasques en diferents nuclis de CPU.
Creació de Fils en C++
En C++, la biblioteca <thread> proporciona les eines necessàries per treballar amb fils. A continuació es mostra un exemple bàsic de com crear i gestionar fils.
Exemple Bàsic
#include <iostream>
#include <thread>
// Funció que serà executada en un fil separat
void funcioFil() {
std::cout << "Hola des del fil!" << std::endl;
}
int main() {
// Crear un fil que executa la funció 'funcioFil'
std::thread fil(funcioFil);
// Esperar que el fil acabi
fil.join();
std::cout << "Hola des del fil principal!" << std::endl;
return 0;
}Explicació del Codi
- Incloure la Biblioteca
<thread>: Necessària per treballar amb fils. - Funció
funcioFil: Aquesta funció serà executada en un fil separat. - Crear un Fil: Utilitzem el constructor de
std::threadper crear un nou fil que executafuncioFil. - Esperar que el Fil Acabi: Utilitzem
join()per esperar que el fil acabi abans de continuar amb el fil principal.
Sincronització de Fils
Quan múltiples fils accedeixen a recursos compartits, és crucial sincronitzar-los per evitar condicions de carrera (race conditions). La biblioteca <mutex> proporciona mecanismes per a la sincronització.
Exemple amb std::mutex
#include <iostream>
#include <thread>
#include <mutex>
std::mutex mtx;
void funcioFil(int id) {
// Bloquejar el mutex
mtx.lock();
std::cout << "Fil " << id << " està executant" << std::endl;
// Desbloquejar el mutex
mtx.unlock();
}
int main() {
std::thread fils[5];
// Crear 5 fils
for (int i = 0; i < 5; ++i) {
fils[i] = std::thread(funcioFil, i);
}
// Esperar que tots els fils acabin
for (int i = 0; i < 5; ++i) {
fils[i].join();
}
return 0;
}Explicació del Codi
- Incloure la Biblioteca
<mutex>: Necessària per treballar amb mutex. - Crear un
std::mutex: Un objecte mutex per a la sincronització. - Bloquejar i Desbloquejar el Mutex: Utilitzem
mtx.lock()imtx.unlock()per assegurar que només un fil accedeixi a la secció crítica al mateix temps.
Exercicis Pràctics
Exercici 1: Crear i Gestionar Fils
Descripció: Escriu un programa que creï tres fils, cadascun dels quals imprimeixi un missatge diferent.
Solució:
#include <iostream>
#include <thread>
void funcioFil1() {
std::cout << "Fil 1 està executant" << std::endl;
}
void funcioFil2() {
std::cout << "Fil 2 està executant" << std::endl;
}
void funcioFil3() {
std::cout << "Fil 3 està executant" << std::endl;
}
int main() {
std::thread fil1(funcioFil1);
std::thread fil2(funcioFil2);
std::thread fil3(funcioFil3);
fil1.join();
fil2.join();
fil3.join();
return 0;
}Exercici 2: Sincronització amb std::mutex
Descripció: Modifica l'exemple anterior per utilitzar un std::mutex per sincronitzar l'accés a la consola.
Solució:
#include <iostream>
#include <thread>
#include <mutex>
std::mutex mtx;
void funcioFil(int id) {
mtx.lock();
std::cout << "Fil " << id << " està executant" << std::endl;
mtx.unlock();
}
int main() {
std::thread fils[3];
for (int i = 0; i < 3; ++i) {
fils[i] = std::thread(funcioFil, i + 1);
}
for (int i = 0; i < 3; ++i) {
fils[i].join();
}
return 0;
}Errors Comuns i Consells
- Oblidar
join(): Si no esperes que els fils acabin ambjoin(), el programa pot acabar abans que els fils hagin completat la seva execució. - Condicions de Carrera: Sempre utilitza mecanismes de sincronització com
std::mutexquan múltiples fils accedeixen a recursos compartits. - Bloqueig de Mutex: Assegura't de desbloquejar el mutex després d'usar-lo per evitar bloquejos (deadlocks).
Conclusió
El multifil és una tècnica poderosa per millorar el rendiment de les aplicacions, però requereix una gestió acurada per evitar problemes de concurrència. Amb els conceptes i exemples proporcionats, hauríeu de tenir una bona base per començar a treballar amb fils en C++.
Curs de Programació en C++
Mòdul 1: Introducció al C++
- Introducció al C++
- Configuració de l'Entorn de Desenvolupament
- Sintaxi i Estructura Bàsica
- Variables i Tipus de Dades
- Entrada i Sortida
Mòdul 2: Estructures de Control
Mòdul 3: Funcions
- Introducció a les Funcions
- Paràmetres de Funció i Tipus de Retorn
- Sobrecàrrega de Funcions
- Recursivitat
Mòdul 4: Arrays i Strings
Mòdul 5: Punteres i Referències
- Introducció als Punteres
- Aritmètica de Punteres
- Punteres i Arrays
- Referències
- Assignació Dinàmica de Memòria
Mòdul 6: Programació Orientada a Objectes
- Introducció a la POO
- Classes i Objectes
- Constructors i Destructors
- Herència
- Polimorfisme
- Encapsulació i Abstracció
Mòdul 7: Temes Avançats
- Plantilles
- Gestió d'Excepcions
- Entrada/Sortida de Fitxers
- Biblioteca de Plantilles Estàndard (STL)
- Expressions Lambda
- Multifil
