C++0X Thread Class

Schnelle objektorientierte, kompilierende Programmiersprache.
Benutzeravatar
Fisherman
Beiträge: 84
Registriert: Mi Jun 06, 2012 4:53 am
Wohnort: 127.0.0.1

C++0X Thread Class

Beitrag von Fisherman » Fr Dez 14, 2012 2:36 pm

Hallo zusammen,

ich lese mich gerade ein bisschen in C++0X ein und bin einfach nur begeistert von der Möglichkeit nun auf unkomplizierte Art und Weise Klassen als Threads laufen zu lassen.
Früher mußte man Zeiger verbiegen, bis einem "schlecht" wurde um dies zu erreichen ...

Hier ein kleines Hello World - Beispiel :
g++ -pthread -o helloclass helloclass.cpp -std=c++0x

Code: Alles auswählen

#include <iostream>
#include <thread>

class bgthread
{
private:
        void printtext()
        {
                std::cout << "Thread Class says HelloWorld\n";
        }
public:
        void printit()
        {
                int loop = 10;
                while (loop > 0)
                {
                        this->printtext();
                        --loop;
                }
        }
};

int main()
{
        bgthread x;
        std::thread th(&bgthread::printit,&x);
        th.join();
        return 0;
}
Vielleicht hilft dies dem ein oder anderen ....

Gruß Fisherman
There is no place like 127.0.0.1

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8862
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: C++0X Thread Class

Beitrag von Xin » Fr Dez 14, 2012 6:40 pm

Schreib es etwas ausführlicher und mache einen Artikel daraus. Solche Informationen sollten möglichst im Wiki landen.
Merke: Wer Ordnung hellt ist nicht zwangsläufig eine Leuchte.

Ich beantworte keine generellen Programmierfragen per PN oder Mail. Dafür ist das Forum da.

Benutzeravatar
Fisherman
Beiträge: 84
Registriert: Mi Jun 06, 2012 4:53 am
Wohnort: 127.0.0.1

Re: C++0X Thread Class

Beitrag von Fisherman » Fr Dez 14, 2012 8:17 pm

OK, bin dabei ;)

Werde mir das "Wortzähl-Projekt" vornehmen und versuchen mit der Hilfe von Threads deinem Sieger-Algorithmus noch ein bissle Kerosin zu verpassen ;)

Gruß Fisherman
There is no place like 127.0.0.1

Benutzeravatar
Fisherman
Beiträge: 84
Registriert: Mi Jun 06, 2012 4:53 am
Wohnort: 127.0.0.1

Re: C++0X Thread Class

Beitrag von Fisherman » Sa Dez 15, 2012 5:30 pm

Salute,

also direkt ein dokuWiki wird es wohl doch nicht - mir fehlt die Zeit dazu.
Wer aber etwas über c++0x erfahren möchte sei auf das engl. Tutorial verwiesen.

Generell läßt sich aber festhalten, dass Threads einen enormen Performance-Schub auslösen und man dieses Thema nicht ignorieren sollte. Auch sind neue Zeitmessroutinen (std::chrono) hinzugekommen, die wirklich erstklassig sind!

Hier mal eine Testausgabe meines heutigen Ergebnisses [Debug]
Sequentiell: Xin_Speed Algorithmus - Thread: 4 x Xin Speed Algorithmus parallel

Code: Alles auswählen

Lasse nun alle 4 Buffer sequentiell durchrechnen...
Anzahl Wörter :200640001
Anzahl Wörter :200640001
Anzahl Wörter :200640001
Anzahl Wörter :200640001
Gesamtzeit : 5530 ms
Lasse nun 4 Threads jeweils 1 Buffer berechnen ...
Anzahl Wörter :200640001
Anzahl Wörter :200640001
Anzahl Wörter :200640001
Anzahl Wörter :200640001
Gesamtzeit : 2570 ms
Threads waren 215.175 % schneller
Gruß Fisherman
There is no place like 127.0.0.1

Benutzeravatar
Fisherman
Beiträge: 84
Registriert: Mi Jun 06, 2012 4:53 am
Wohnort: 127.0.0.1

Re: C++0X Thread Class

Beitrag von Fisherman » Sa Dez 15, 2012 10:19 pm

Ein wenig kommt doch noch zum Thema <random> und C++0x

Es wurden ein paar Neuerungen bzgl. des Zufallsgenerators eingebaut. Man kann nun unter verschiedenen Generatoren wählen. eine Liste der Zufallsgeneratoren ist hier aufgelistet.

Die ebend angesprochene Chrono Bibliothek soll im folgenden verwendet werden um den mt19937_64 (64bit) zu initialisieren. Im Prinzip genauso wie früher mittels time(NULL) nur halt "moderner" ...

Ich habe jeweils ein kleines Beispielprogramm zu den folgenden Themen geschrieben um das ganze besser zu verdeutlichen:

ChronoSeed.cpp

Code: Alles auswählen

#include <chrono>
#include <iostream>

/*
   RandomSeed by Chrono
   Liefert einen Ersatz für die Initialisierung des Zufallsgenerators

   g++ -std=gnu++0x ChronoSeed.cpp -o ChronoSeed
*/


int main()
{
  std::cout << "Zeiten:" << std::endl;
  for (int i=0; i < 10; ++i)
    std::cout << (std::chrono::high_resolution_clock::now().time_since_epoch().count()) << std::endl;
  return 0;
}
Wer ganzzahlige Zufallszahlen aus einer bestimmten Menge von a bis b benötigt dem sei die Uniform INT Distribution ans Herz gelegt. Mit diesem Code kann man leicht die gewünschten Zufallszahlen generieren. Auch ist es möglich von negativen Ganzzahlen bis hin zu positiven Ganzzahlen eine Menge zu erhalten.

UniformINTDistribution.cpp

Code: Alles auswählen

#include <random>
#include <chrono>
#include <iostream>

/*
   Uniform INT distribution
   Liefert ganzzahlige Zufahlszahlen aus der Menge [int]min. bis [int]max.

   g++ -std=gnu++0x UniformINTDistribution.cpp -o UniformINTDistribution
*/


int main()
{
	// Zufallsgenerator initalisieren (64bit Variante)
	std::mt19937_64 eng(std::chrono::high_resolution_clock::now().time_since_epoch().count());

	int min = 2, max = 8;
	std::cout << "Uniform INT Distribution :[" << min << "," << max << "]" << std::endl;
        // Bereich festlegen aus der die Zahlen generiert werden sollen
        std::uniform_int_distribution<int> uniform_int(min,max);
	for (int i=0; i < 10; ++i)
          {
	    for(int j=0; j < 10; ++j)
	    {
	       // Zufallszahl aus Bereich ausgeben
	       std::cout << uniform_int(eng) << " ";
	    }
          std::cout << std::endl; 
          }
	return 0;
}
Das gleiche gibt es auch für Fließkommazahlen und nennt sich UniformREALDistribution.

UniformREALDistribution.cpp

Code: Alles auswählen

#include <random>
#include <chrono>
#include <iostream>

/*
   Uniform REAL distribution
   Liefert Fliesskomma Zufahlszahlen aus der Menge [double]min. bis [double]max.

   g++ -std=gnu++0x UniformREALDistribution.cpp -o UniformREALDistribution
*/


int main()
{
	// Zufallsgenerator initalisieren (64bit Variante)
	std::mt19937_64 eng(std::chrono::high_resolution_clock::now().time_since_epoch().count());

	double min = 0.1, max = 0.9;
	std::cout << "Uniform REAL Distribution :[" << min << "," << max << "]" << std::endl;
        // Bereich festlegen aus der die Zahlen generiert werden sollen
        std::uniform_real_distribution<double> uniform_real(min,max);
	for (int i=0; i < 10; ++i)
          {
	    for(int j=0; j < 10; ++j)
	    {
               std::cout.fill(' ');
               std::cout.width(10);
	       // Zufallszahl aus Bereich ausgeben
	       std::cout << std::left << uniform_real(eng) << " ";
	    }
          std::cout << std::endl; 
          }
	return 0;
}
Dann haben wir noch die Möglichkeit uns einen zufälligen dualen Wert ausgeben zu lassen. Hierbei kann die Gewichtung wie die "Münze" fallen soll beeinflusst werden je nach Wunsch. Dabei ist allerdings von größeren Mengen auszugehen, die dann in der Summe die gewünschte Gewichtung haben. Man kann allerdings schon bei kleineren Mengen den Unterschied erkennen.

BernoulliDistribution.cpp

Code: Alles auswählen

#include <random>
#include <chrono>
#include <iostream>

/*
   Bernoulli Distribution
   Liefert ein dualen Wert ähnlich einem Münzwurf.

   g++ -std=gnu++0x BernoulliDistribution.cpp -o BernoulliDistribution
*/


int main()
{
	// Zufallsgenerator initalisieren (64bit Variante)
	std::mt19937_64 eng(std::chrono::high_resolution_clock::now().time_since_epoch().count());

	double p = 0.5;
	std::cout << "Bernoulli Distribution :[" << p << "]" << std::endl;
        // Gewichtung der mengenmäßigen Verteilung festlegen
        // 0.25 = 25[0] / 75[1]
        // 0.5  = 50[0] / 50[1]
        // 0.75 = 25[0] / 75[1]
        std::bernoulli_distribution bernoulli(p);
	for (int i=0; i < 10; ++i)
          {
	    for(int j=0; j < 10; ++j)
	    {
	       // Münze werfen ...
	       std::cout << bernoulli(eng) << " ";
	    }
          std::cout << std::endl; 
          }
	return 0;
}
Alle Beispiele sind unter Linux Debian getestet und mit g++ -std=gnu++0x zu kompilieren.
[gcc version 4.7.2 (Debian 4.7.2-4)]

Gruß Fisherman
There is no place like 127.0.0.1

Benutzeravatar
Fisherman
Beiträge: 84
Registriert: Mi Jun 06, 2012 4:53 am
Wohnort: 127.0.0.1

Re: C++0X Thread Class

Beitrag von Fisherman » So Dez 16, 2012 12:50 am

Und weil ich im Moment nicht genug von C++0x bekommen kann, da ich immer wieder etwas neues entdecke - hier noch ein nettes Feature. Die Auto Datentyp Erkennung. Vorbei die Zeiten in den man sich Sorgen um den richtigen Datentyp machen mußte. Mit auto wird die Entscheidung direkt dem Compiler überlassen. Einzig muß bei der Deklaration der Variable auch eine Initialisierung erfolgen.

Auto kann auch in Schleifen benutzt werden und so richtig dreht der neue "Befehl" bei Iteratoren von STL Containern auf. Aber genug der Rede - schaut euch den Beispielcode an, den ich ebend zum Thema zusammengestellt habe, nachdem ich das nette Video von Herb Sutter gesehen habe.

Das Beste an der ganzen Sache hier ist, das man keine extra Bibliotheken installieren muss - nur falls es noch nicht aufgefallen sein sollte !!! ;)

AutoType.cpp

Code: Alles auswählen

#include <iostream>
#include <vector>

/*
   AutoType.cpp
   Die Einführung von 'auto' ist eine der größten Änderungen
   in C++0x. Mit auto kann die Entscheidung um welchen Datentyp
   es sich handelt, dem Compiler überlassen werden.

   g++ -std=gnu++0x AutoType.cpp -o AutoType
*/

int main()
{
  auto i = 10, j = 20;
  auto d = 0.753, e = 0.107;
 
  std::cout << "Addiere " << i << " + " << j << " = " << (i+j) << std::endl;
  std::cout << "Addiere " << d << " + " << e << " = " << (d+e) << std::endl;
  std::cout << "Addiere " << (i+j) << " + " << (d+e) << " = " << (i+j+d+e) << std::endl;

  i = 30;
  d = 0.5;

  std::cout << "Dividiere " << i << " durch " << d << " = " << (i/d) << std::endl;
  std::cout << "Multipliziere " << i << " mit " << d << " = " << (i*d) << std::endl;

  std::cout << "Auto funktioniert auch in Schleifen" << std::endl;
  for (auto x = 10; x > 0; --x)
    std::cout << x << " ";

  std::cout << "\n";

  std::cout << "Auch die STL Container können mit auto arbeiten" << std::endl;
  std::vector<int> myVec {1,2,3,4,5};

  auto total = 0;
  for ( auto it : myVec)
  {
    std::cout << it << " ";
    total += it;
  }
  std::cout << " Summe = " << total << std::endl;

  return 0;
}
Gruß Fisherman
There is no place like 127.0.0.1

sebix
Beiträge: 82
Registriert: Mo Nov 19, 2012 8:27 pm

Re: C++0X Thread Class

Beitrag von sebix » Mo Dez 17, 2012 9:35 pm

Den Auto-"Datentypen" kenn ich ja schon, besonders bei den Iteratoren liebe ich ihn, but wait: What's that?

Code: Alles auswählen

for ( auto it : myVec)
Was ist denn das für eine geniale Schleifendefinition?!

Benutzeravatar
Fisherman
Beiträge: 84
Registriert: Mi Jun 06, 2012 4:53 am
Wohnort: 127.0.0.1

Re: C++0X Thread Class

Beitrag von Fisherman » Di Dez 18, 2012 3:35 am

Genau - intuitives programmieren ....

Vielleicht interessiert Dich auch noch der folgende Artikel. Hier geht es um die Lambda Funktion, oder einfacher ausgedrückt um namenlose inline Funktionen.
There is no place like 127.0.0.1

Benutzeravatar
Kerli
Beiträge: 1456
Registriert: So Jul 06, 2008 10:17 am
Wohnort: Österreich
Kontaktdaten:

Re: C++0X Thread Class

Beitrag von Kerli » Di Dez 18, 2012 11:49 am

Lambda Funktionen gibt es auch bei uns im Wiki ;)

Übrigens mit 'auto' würde ich sparsam umgehen. Wenn der Typ bekannt ist und vor allem wenn dieser auch nicht übermäßig kompliziert ist (zb. kein Typ irgendwie in ein Template eingepackt) würde ich auf jeden Fall den Typ ausschreiben. Das ist meistens gleich schnell (bei 'int' statt 'auto' sogar schneller ;)) und macht den Code leichter lesbar bzw. auch weniger anfällig gegen Fehler, da nicht durch eine unscheinbar Änderung der Typ geändert werden kann:

Code: Alles auswählen

auto total = 0.5; // total ist vom Typ double
auto total = 1;    // Jetzt wird total vermutlich int oder etwas ähnliches sein
float total = 1;    // So ist man sicher dass total float bleibt, egal welchen Wert man verwendet
"Make it idiot-proof and someone will invent an even better idiot." (programmers wisdom)

OpenGL Tutorials und vieles mehr rund ums Programmieren: http://www.tomprogs.at

sebix
Beiträge: 82
Registriert: Mo Nov 19, 2012 8:27 pm

Re: C++0X Thread Class

Beitrag von sebix » Di Dez 18, 2012 7:11 pm

Vielen Dank für die beiden Links, so wird C++-Code doch noch lesbarer!

Antworten