Quelqu'un peut-il publier un exemple simple de démarrage de deux threads (orientés objet) en C++.
Je recherche des objets de threads C++ réels sur lesquels je peux étendre les méthodes d'exécution (ou quelque chose de similaire), par opposition à l'appel d'une bibliothèque de threads de style C.
Mise à jour - J'ai omis toute requête spécifique à un système d'exploitation dans l'espoir que celui qui répondrait répondrait avec des bibliothèques multi-plateformes à utiliser. Je ne fais que l'expliciter maintenant.
Créez une fonction que vous voulez que le thread exécute, par exemple:
void task1(std::string msg)
{
std::cout << "task1 says: " << msg;
}
Créez maintenant l’objet thread
qui appellera finalement la fonction ci-dessus de la manière suivante:
std::thread t1(task1, "Hello");
(Vous devez #include <thread>
pour accéder à la classe std::thread
)
Les arguments du constructeur sont la fonction que le thread va exécuter, suivie des paramètres de la fonction. Le fil est automatiquement lancé lors de la construction.
Si plus tard vous voulez attendre que le thread ait fini d'exécuter la fonction, appelez:
t1.join();
(Rejoindre signifie que le thread qui a appelé le nouveau thread attendra que le nouveau thread termine son exécution avant de poursuivre sa propre exécution).
#include <string>
#include <iostream>
#include <thread>
using namespace std;
// The function we want to execute on the new thread.
void task1(string msg)
{
cout << "task1 says: " << msg;
}
int main()
{
// Constructs the new thread and runs it. Does not block execution.
thread t1(task1, "Hello");
// Do other things...
// Makes the main thread wait for the new thread to finish execution, therefore blocks its own execution.
t1.join();
}
Plus d'informations sur std :: thread ici
-std=c++0x -pthread
.Techniquement, un tel objet finira par être construit sur une bibliothèque de threads de style C, car C++ vient juste de spécifier un stock std::thread
modèle en c ++ 0x, qui vient juste d'être cloué et qui n'a pas encore été implémenté. Le problème est quelque peu systémique. Techniquement, le modèle de mémoire c ++ existant n’est pas assez strict pour permettre une sémantique bien définie pour tous les cas «se produit avant». Hans Boehm a écrit un article sur le sujet il y a quelque temps et a joué un rôle déterminant dans l'élaboration de la norme c ++ 0x sur le sujet.
http://www.hpl.hp.com/techreports/2004/HPL-2004-209.html
Cela dit, il existe plusieurs bibliothèques de threads C++ inter-plateformes qui fonctionnent parfaitement dans la pratique. Les blocs de construction de threads Intel contiennent un objet tbb :: thread qui se rapproche beaucoup de la norme c ++ 0x et Boost a une bibliothèque boost :: thread qui en fait de même.
http://www.threadingbuildingblocks.org/
http://www.boost.org/doc/libs/1_37_0/doc/html/thread.html
En utilisant boost :: thread, vous obtiendrez quelque chose comme:
#include <boost/thread.hpp>
void task1() {
// do stuff
}
void task2() {
// do stuff
}
int main (int argc, char ** argv) {
using namespace boost;
thread thread_1 = thread(task1);
thread thread_2 = thread(task2);
// do other stuff
thread_2.join();
thread_1.join();
return 0;
}
Il existe également une bibliothèque POSIX pour les systèmes d'exploitation POSIX. Vérifier pour la compatibilité
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <iostream>
void *task(void *argument){
char* msg;
msg = (char*)argument;
std::cout<<msg<<std::endl;
}
int main(){
pthread_t thread1, thread2;
int i1,i2;
i1 = pthread_create( &thread1, NULL, task, (void*) "thread 1");
i2 = pthread_create( &thread2, NULL, task, (void*) "thread 2");
pthread_join(thread1,NULL);
pthread_join(thread2,NULL);
return 0;
}
compiler avec -lpthread
Voici un moyen plus robuste de créer un nombre arbitraire de threads (en C++ 11 ou plus récent):
#include <thread>
#include <iostream>
using namespace std;
void doSomething(int id) {
cout << "Thread id = " << id;
}
/**
* Spawns n threads
*/
void spawnThreads(int n)
{
thread threads[n];
// spawn n threads:
for (int i = 0; i < n; i++) {
threads[i] = thread(doSomething, i + 1);
}
for (auto& th : threads) {
th.join();
}
}
Lorsque vous recherchez un exemple de classe C++ qui appelle l'une de ses propres méthodes d'instance dans un nouveau thread, cette question se pose, mais nous n'avons pas pu utiliser ces réponses de cette façon. Voici un exemple qui fait ça:
Classe.h
class DataManager
{
public:
bool hasData;
void getData();
bool dataAvailable();
};
Class.cpp
#include "DataManager.h"
void DataManager::getData()
{
// perform background data munging
hasData = true;
// be sure to notify on the main thread
}
bool DataManager::dataAvailable()
{
if (hasData)
{
return true;
}
else
{
std::thread t(&DataManager::getData, this);
t.detach(); // as opposed to .join, which runs on the current thread
}
}
Notez que cet exemple n'entre pas dans le mutex ou le verrouillage.
Cela dépend en grande partie de la bibliothèque que vous décidez d'utiliser. Par exemple, si vous utilisez la bibliothèque wxWidgets, la création d'un fil ressemblerait à ceci:
class RThread : public wxThread {
public:
RThread()
: wxThread(wxTHREAD_JOINABLE){
}
private:
RThread(const RThread ©);
public:
void *Entry(void){
//Do...
return 0;
}
};
wxThread *CreateThread() {
//Create thread
wxThread *_hThread = new RThread();
//Start thread
_hThread->Create();
_hThread->Run();
return _hThread;
}
Si votre thread principal appelle la méthode CreateThread, vous créerez un nouveau thread qui commencera à exécuter le code dans votre méthode "Entry". Vous devrez garder une référence au fil dans la plupart des cas pour le rejoindre ou l’arrêter . Plus d'infos ici: Documentation wxThread
À moins de vouloir une fonction séparée dans les espaces de noms globaux, nous pouvons utiliser les fonctions lambda pour créer des threads.
L'un des principaux avantages de la création de thread à l'aide de lambda est qu'il n'est pas nécessaire de transmettre des paramètres locaux sous forme de liste d'arguments. Nous pouvons utiliser la liste de capture pour la même chose et la propriété de fermeture de lambda prendra en charge le cycle de vie.
Voici un exemple de code
int main() {
int localVariable = 100;
thread th { [=](){
cout<<"The Value of local variable => "<<localVariable<<endl;
}}
th.join();
return 0;
}
De loin, j'ai trouvé que les lambdas C++ étaient le meilleur moyen de créer des threads, en particulier pour des fonctions de thread plus simples.
// multithreaded.c ++: Exemple simple de threading en C++ utilisant le threading et la section critique.
#include "stdafx.h"
#include <thread>
#include <iostream>
#include<fstream>
#include <windows.h>
using namespace std;
bool flag = 1;
auto path = "D:\\temp";
void writestatus(int i, int j);
CRITICAL_SECTION cs;
void workerThread(int j)
{
int i = 1;
ofstream f2;
char buff[150] = { 0 };
while (flag)
{
sprintf_s(buff, 150, "D:\\temp\\MyTemp_%d%03d.txt", j, i++);
//str.append("%d", i++);
f2.open(buff);
f2 << buff;
f2.close();
//Sleep(10);
}
EnterCriticalSection(&cs);
writestatus(i, j);
LeaveCriticalSection(&cs);
}
void writestatus(int i, int j)
{
ofstream f1;
char buff[150] = { 0 };
f1.open("D:\\temp\\status.txt", ios_base::app);
sprintf_s(buff, 150, "%d Writes %d files \n", j, i++);
if (f1)
{
f1 << buff;
}
else
{
MessageBeep(1);
}
f1.close();
}
int main()
{
system("del d:\\temp\\*.txt");
InitializeCriticalSection(&cs);
thread t1(workerThread, 1);
thread t2(workerThread, 2);
thread t3(workerThread, 3);
thread t4(workerThread, 4);
thread t5(workerThread, 5);
Sleep(250);
flag = 0;
t1.join();
t2.join();
t3.join();
t4.join();
t5.join();
return 0;
}