Je suis nouveau dans c ++ et je cherchais des didacticiels de threads multiplateformes c ++. Je regardais ceci: http://solarianprogrammer.com/2011/12/16/cpp-11-thread-tutorial/
et essayait d'exécuter le code suivant:
#include <iostream>
#include <thread>
static const int num_threads = 10;
//This function will be called from a thread
void call_from_thread(int tid) {
std::cout << "Launched by thread " << tid << std::endl;
}
int main() {
std::thread t[num_threads];
//Launch a group of threads
for (int i = 0; i < num_threads; ++i) {
t[i] = std::thread(call_from_thread, i);
}
std::cout << "Launched from the main\n";
//Join the threads with the main thread
for (int i = 0; i < num_threads; ++i) {
t[i].join();
}
return 0;
}
La sortie que j'obtiens est la suivante et je ne comprends pas pourquoi:
syd@syd-HP-Compaq-dx7500-Microtower:~/Desktop$ ./ref
Launched by thread Launched by thread Launched by thread Launched by thread Launched by thread 201
Launched by thread 5
Launched by thread 6
4
Launched by thread 7
3
Launched by thread 8
Launched from the main
Launched by thread 9
Je comprends que les nombres sont aléatoires à chaque fois, mais parfois je ne reçois aucun chiffre et je me demande pourquoi?
Ils sont tous là. Ils sont simplement mutilés parce que la sortie de la console se produit dans des ordres vaguement aléatoires.
Jetez un œil en particulier à la fin de la première ligne de sortie.
il vous suffit d'ajouter un mutex et de le verrouiller dans la bonne position:
std::mutex mtx;
-
void call_from_thread(int tid) {
mtx.lock();
-----------------------------------------------------------
std::cout << "Launched by thread " << tid << std::endl;
-----------------------------------------------------------
mtx.unlock();
}
-
mtx.lock();
-----------------------------------------------------------
std::cout << "Launched from the main\n";
-----------------------------------------------------------
mtx.unlock();
Il y a une condition de concurrence dans IO (cout)
std::cout << "Launched by thread " << tid << std::endl;
En fait, il n'y a aucune garantie de séquencement cout ("Lancé par thread", tid, std :: endl). Et cela se comporte comme ceci:
std::cout << "Launched by thread " ;
cout<< tid ;
cout<< std::endl;
Vous pouvez changer call_from_thread en:
void call_from_thread(int tid) {
std::cout << std::string("Launched by thread " + std::to_string(tid) + "\n");
}
Le point suivant est
t[i] = std::thread(call_from_thread, i);
Lorsque vous créez un thread, au moment de la création, la fonction call_from_thread sera appelée.
Il vaut donc mieux bouger
std::cout << "Launched from the main\n";
Avant
//Launch a group of threads
for (int i = 0; i < num_threads; ++i) {
t[i] = std::thread(call_from_thread, i);
}
Vous pouvez également utiliser titulaires :
mutex g_i_mutex; // protects cout
void call_from_thread(int tid) {
lock_guard<mutex> lock(g_i_mutex);
cout << "Launched by thread " ;
cout<< tid ;
cout<< std::endl;
}