Einfaches Beispiel für Threading in C++

Lesezeit: 9 Minuten

Einfaches Beispiel fur Threading in C
Zak

Kann jemand ein einfaches Beispiel für das Starten von zwei (objektorientierten) Threads in C++ posten.

Ich suche nach tatsächlichen C++-Thread-Objekten, auf die ich Run-Methoden (oder ähnliches) erweitern kann, anstatt eine Thread-Bibliothek im C-Stil aufzurufen.

Ich habe alle betriebssystemspezifischen Anfragen ausgelassen, in der Hoffnung, dass jeder, der geantwortet hat, mit plattformübergreifenden Bibliotheken antworten würde, die verwendet werden können. Ich drücke das jetzt nur explizit aus.

  • Diese Frage wird auf Meta diskutiert

    – Zoe steht mit der Ukraine

    13. August 2019 um 12:46 Uhr

Einfaches Beispiel fur Threading in C
MasterMastix

Erstellen Sie eine Funktion, die der Thread ausführen soll, z.

void task1(std::string msg)
{
    std::cout << "task1 says: " << msg;
}

Erstellen Sie nun die thread Objekt, das letztendlich die obige Funktion wie folgt aufruft:

std::thread t1(task1, "Hello");

(Du musst #include <thread> um auf die zuzugreifen std::thread Klasse)

Die Argumente des Konstruktors sind die Funktion, die der Thread ausführt, gefolgt von den Parametern der Funktion. Der Thread wird automatisch bei der Konstruktion gestartet.

Wenn Sie später warten möchten, bis der Thread mit der Ausführung der Funktion fertig ist, rufen Sie Folgendes auf:

t1.join(); 

(Beitreten bedeutet, dass der Thread, der den neuen Thread aufgerufen hat, darauf wartet, dass der neue Thread die Ausführung beendet, bevor er seine eigene Ausführung fortsetzt).


Der Code

#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();
}

Weitere Informationen zu std::thread hier

  • Kompilieren Sie auf GCC mit -std=c++0x -pthread.
  • Dies sollte für jedes Betriebssystem funktionieren, sofern Ihr Compiler diese Funktion (C++11) unterstützt.

  • @Preza8 VS10 unterstützt viele Funktionen in C++11 nicht. VS12- und VS13-Support-Thread.

    – jodag

    9. Januar 2014 um 0:53 Uhr


  • Im Kommentar “GCC-Versionen unter 4.7 verwenden -std=c++0x (anstatt -std=c++0x)” Ich glaube, das zweite “c++0x” sollte stattdessen “c++11” sein, aber das kann nicht geändert werden, weil die Bearbeitung zu klein ist.

    – zentrunix

    25. März 2014 um 16:19 Uhr

  • @MasterMastic Welchen Unterschied macht es, wenn wir anstelle von std::thread t1(task1, “Hallo”) std::thread t1(&task1, “Hallo”) verwenden und die Referenz der Funktion übergeben? Sollten wir die Funktion in diesem Fall als Zeiger deklarieren?

    – Benutzer2452253

    4. November 2014 um 16:32 Uhr


  • @ user2452253 Wenn Sie “task1” übergeben, übergeben Sie einen Zeiger auf die Funktion, die Sie ausführen möchten (was gut ist). Wenn Sie “&task1” übergeben, übergeben Sie einen Zeiger auf einen Zeiger einer Funktion, und die Ergebnisse wären wahrscheinlich nicht so hübsch und sehr undefiniert (es wäre, als würden Sie versuchen, zufällige Anweisungen nacheinander auszuführen. Mit der richtigen Wahrscheinlichkeit Sie nur vielleicht öffne das Tor zur Hölle). Sie möchten wirklich nur den Funktionszeiger übergeben (ein Zeiger mit dem Wert der Adresse, an der die Funktion beginnt). Wenn das die Dinge nicht klärt, lass es mich wissen und viel Glück!

    – MasterMastic

    4. November 2014 um 16:47 Uhr

  • @curiousguy Nun, der richtige Weg, dies zu tun, besteht darin, einen Zeiger auf die Funktion zu übergeben, die Sie ausführen möchten. In diesem Fall ist die Funktion task1. Daher wird der Funktionszeiger auch mit bezeichnet task1. Aber danke, dass Sie das angesprochen haben, denn ich glaube, ich habe mich geirrt und es ist gleichbedeutend mit &task1also spielt es keine Rolle, welche Form Sie schreiben (wenn ja, denke ich, dass Zeiger auf Zeiger der Funktion ist &&task1das wäre schlecht). Relevante Frage.

    – MasterMastic

    5. Juli 2018 um 9:22 Uhr

1646960414 28 Einfaches Beispiel fur Threading in C
Eduard Kmett

Nun, technisch gesehen wird jedes solche Objekt über eine Thread-Bibliothek im C-Stil gebaut, weil C++ nur einen Bestand spezifiziert hat std::thread -Modell in c++0x, das gerade festgenagelt und noch nicht implementiert wurde. Das Problem ist etwas systemisch, technisch gesehen ist das vorhandene C++-Speichermodell nicht streng genug, um eine gut definierte Semantik für alle „passiert vorher“-Fälle zu ermöglichen. Hans Böhm hat vor einiger Zeit ein Papier zu diesem Thema geschrieben und war maßgeblich an der Ausarbeitung des c++0x-Standards zu diesem Thema beteiligt.

http://www.hpl.hp.com/techreports/2004/HPL-2004-209.html

Allerdings gibt es mehrere plattformübergreifende Thread-C++-Bibliotheken, die in der Praxis gut funktionieren. Intel-Thread-Bausteine ​​enthalten ein tbb::thread-Objekt, das dem c++0x-Standard sehr nahe kommt, und Boost hat eine boost::thread-Bibliothek, die dasselbe tut.

http://www.threadingbuildingblocks.org/

http://www.boost.org/doc/libs/1_37_0/doc/html/thread.html

Mit boost::thread erhalten Sie so etwas wie:

#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;
}

  • Boost-Thread ist großartig – mein einziges Problem war, dass Sie (als ich es zuletzt benutzte) nicht auf das native zugrunde liegende Thread-Handle zugreifen konnten, da es sich um ein privates Klassenmitglied handelte! Es gibt eine MENGE Zeug in win32, für das Sie das Threadhandle brauchen, also haben wir es optimiert, um das Handle öffentlich zu machen.

    – Orion Edwards

    5. November 2008 um 19:40 Uhr

  • Ein weiteres Problem mit boost::thread besteht darin, dass Sie, soweit ich mich erinnere, nicht die Freiheit haben, die Stapelgröße des neuen Threads festzulegen – eine Funktion, die bedauerlicherweise auch nicht im c++0x-Standard enthalten ist.

    – Eduard Kmett

    5. November 2008 um 20:13 Uhr

  • Dieser Code gibt mir eine boost::noncopyable-Ausnahme für diese Zeile: thread thread_1 = thread(task1); Vielleicht liegt es daran, dass ich eine ältere Version (1.32) verwende.

    – Frank

    21. Februar 2009 um 0:42 Uhr

  • task1 wurde nicht in diesem Bereich deklariert?

    – Jake Gaston

    22. März 2019 um 20:45 Uhr

1646960415 601 Einfaches Beispiel fur Threading in C
Caner

#include <thread>
#include <iostream>
#include <vector>
using namespace std;

void doSomething(int id) {
    cout << id << "\n";
}

/**
 * Spawns n threads
 */
void spawnThreads(int n)
{
    std::vector<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();
    }
}

int main()
{
    spawnThreads(10);
}

1646960415 856 Einfaches Beispiel fur Threading in C
Hohenheimsenberg

Es gibt auch eine POSIX-Bibliothek für POSIX-Betriebssysteme.
Überprüfen für Kompatibilität

#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;

}

mit -lpthread kompilieren

http://en.wikipedia.org/wiki/POSIX_Threads

Bei der Suche nach einem Beispiel einer C++-Klasse, die in einem neuen Thread eine ihrer eigenen Instanzmethoden aufruft, taucht diese Frage auf, aber wir konnten keine dieser Antworten so verwenden. Hier ist ein Beispiel, das das tut:

Klasse.h

class DataManager
{
public:
    bool hasData;
    void getData();
    bool dataAvailable();
};

Klasse.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
    }
}

Beachten Sie, dass dieses Beispiel nicht in Mutex oder Locking gerät.

  • Danke, dass du das gepostet hast. Beachten Sie, dass die allgemeine Form des Aufrufs einer Thread-on-Instance-Methode etwa so aussieht: Foo f; std::thread t(&Foo::Run, &f, args…); (wobei Foo eine Klasse ist, die ‘Run()’ als Mitgliedsfunktion hat).

    – Jay Elston

    8. Januar 2019 um 19:44 Uhr

  • Danke, dass du das gepostet hast. Ich verstehe ernsthaft nicht, warum alle Threading-Beispiele globale Funktionen verwenden.

    – hk Battousai

    15. Februar 2020 um 13:00 Uhr

  • Ändern Sie dies in shared_from_this, wenn die aktuelle Klasse von enable_shared_from_this abgeleitet ist.

    – Eugen

    1. Februar 2021 um 15:39 Uhr

Einfaches Beispiel fur Threading in C
Don Hatch

Sofern man keine separate Funktion in globalen Namespaces wünscht, können wir Lambda-Funktionen zum Erstellen von Threads verwenden.

Einer der Hauptvorteile beim Erstellen von Threads mit Lambda besteht darin, dass wir keine lokalen Parameter als Argumentliste übergeben müssen. Wir können die Erfassungsliste für dasselbe verwenden, und die Schließungseigenschaft von Lambda kümmert sich um den Lebenszyklus.

Hier ist ein Beispielcode

int main() {
    int localVariable = 100;

    thread th { [=](){
        cout<<"The Value of local variable => "<<localVariable<<endl;
    }};

    th.join();

    return 0;
}

Ich habe bei weitem festgestellt, dass C++-Lambdas die beste Methode zum Erstellen von Threads sind, insbesondere für einfachere Thread-Funktionen

  • Danke, dass du das gepostet hast. Beachten Sie, dass die allgemeine Form des Aufrufs einer Thread-on-Instance-Methode etwa so aussieht: Foo f; std::thread t(&Foo::Run, &f, args…); (wobei Foo eine Klasse ist, die ‘Run()’ als Mitgliedsfunktion hat).

    – Jay Elston

    8. Januar 2019 um 19:44 Uhr

  • Danke, dass du das gepostet hast. Ich verstehe ernsthaft nicht, warum alle Threading-Beispiele globale Funktionen verwenden.

    – hk Battousai

    15. Februar 2020 um 13:00 Uhr

  • Ändern Sie dies in shared_from_this, wenn die aktuelle Klasse von enable_shared_from_this abgeleitet ist.

    – Eugen

    1. Februar 2021 um 15:39 Uhr

Es hängt weitgehend von der Bibliothek ab, für die Sie sich entscheiden. Wenn Sie beispielsweise die wxWidgets-Bibliothek verwenden, würde die Erstellung eines Threads wie folgt aussehen:

class RThread : public wxThread {

public:
    RThread()
        : wxThread(wxTHREAD_JOINABLE){
    }
private:
    RThread(const RThread &copy);

public:
    void *Entry(void){
        //Do...

        return 0;
    }

};

wxThread *CreateThread() {
    //Create thread
    wxThread *_hThread = new RThread();

    //Start thread
    _hThread->Create();
    _hThread->Run();

    return _hThread;
}

Wenn Ihr Haupt-Thread die CreateThread-Methode aufruft, erstellen Sie einen neuen Thread, der mit der Ausführung des Codes in Ihrer „Entry“-Methode beginnt. Sie müssen in den meisten Fällen einen Verweis auf den Thread beibehalten, um ihm beizutreten oder ihn zu stoppen. Mehr Infos hier: wxThread-Dokumentation

  • Du hast vergessen den Thread zu löschen. Vielleicht wollten Sie eine erstellen losgelöst Gewinde?

    – Aib

    5. November 2008 um 18:57 Uhr

  • Ja, richtig, ich habe den Code aus einem Code extrahiert, an dem ich gerade arbeite, und natürlich wird der Verweis auf den Thread irgendwo gespeichert, um ihn später zu verbinden, zu stoppen und zu löschen. Danke. 🙂

    – LorenzCK

    6. November 2008 um 16:06 Uhr

989450cookie-checkEinfaches Beispiel für Threading in C++

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy