Asynchrone und mehrfädige Programmierung in MQL - Seite 34

 
Andrei Novichkov:
Aber ich frage mich, ob es Aufgaben gibt, die wirklich Thread-Pooling erfordern? Nicht nur - einen Thread erstellen, ihn vergessen und warten, bis er abläuft, sondern genau einen Pool, wie Williams ihn beschreibt? Es scheint sich dabei um ein Beispiel für einen Geldautomaten zu handeln, wenn ich mich nicht irre - welche Aufgabe könnte ein solches Wunderwerk rechtfertigen? Ich kann mir eine solche Aufgabe noch nicht vorstellen. Und warum schaust du dir nicht ThreadPool an, wo alles schon gemacht ist, es gibt Dokumentation und Beispiele.

Um ehrlich zu sein, habe ich bisher nicht viel Sinn zwischenstd::async und thread pool gesehen, außer dassstd::async automatisch einen Thread für die aktuelle Aufgabe erstellt und löscht.
Und um das Thread-Pooling zu nutzen, müssen Sie die Anzahl der im Programm verwendeten Threads im Voraus kennen und diese Anzahl explizit für den Pool festlegen.
Es stellt sich heraus, dass die Thread-Pooling ist statisch in Bezug auf die Anzahl der Threads, obwohl dies möglicherweise nicht der Fall ist, kann ich nicht behaupten.
In Williams' Buch heißt es jedoch, dass Thread-Pooling empfohlen wird, wenn sehr viele Aufgaben in std::thread ausgeführt werden sollen.
Und vielleicht gilt das nicht fürstd::async, ich habe die Bedeutung noch nicht ganz begriffen.
Und Asynchronität ist bei Netzwerklösungen und Multisymbol-Strategien sehr gefragt, und auch für belastete Berechnungen ist sie nützlich.
Aber mitstd::async und std::promise im Standard, denke ich, dass es keine Notwendigkeit gibt, einen Thread-Pool zu erstellen.

 

Es gibt auch eine Frage zum Einrichten eines Projekts für dll.
Wie wird man unbenutzte Funktionen los, die von Compilern automatisch in die DLL-Abhängigkeit gezogen werden?

Ich habe bereits verschiedene Entwicklungsumgebungen ausprobiert, und jede von ihnen zieht ihre eigene ungenutzte Funktion.
MSVS_2017 zieht sogar seine eigenen Runtime-Abhängigkeiten, die ich wohl nicht loswerden kann.
Deshalb habe ich verschiedene IDEs ausprobiert, aber auch diese ziehen ungenutzte Funktionen.
Wie wird man sie wieder los?

 
Roman:

Um ehrlich zu sein, habe ich selbst nicht viel Sinn zwischenstd::async und Thread Pooling entdeckt, außer dass std::async automatisch einen Thread für die aktuelle Aufgabe erstellt und löscht.
Und um das Thread-Pooling zu nutzen, müssen Sie die Anzahl der im Programm verwendeten Threads im Voraus kennen und diese Anzahl explizit für den Pool festlegen.
Es stellt sich heraus, dass die Thread-Pooling ist statisch in Bezug auf die Anzahl der Threads, obwohl dies möglicherweise nicht der Fall ist, kann ich nicht behaupten.
In Williams' Buch heißt es jedoch, dass Thread-Pooling empfohlen wird, wenn viele Aufgaben in std::thread ausgeführt werden sollen.
Und vielleicht gilt das nicht fürstd::async, ich habe die Bedeutung noch nicht ganz begriffen.
Und Asynchronität ist bei Netzwerklösungen und Multisymbol-Strategien sehr gefragt, und auch für belastete Berechnungen ist sie nützlich.
Aber mitstd::async und std::promise im Standard, denke ich, dass es keine Notwendigkeit gibt, einen Thread-Pool zu erstellen.

Also der wichtigste Punkt der async ist Thread-Pool zu verwenden, loszuwerden, Thread Erstellung/Löschung Overhead, wenn async nicht tun, dass, dann ist es wertlos.

Nun, eigentlich habe ich anscheinend zu schlecht über async gedacht. Ein einfacher Test zeigt, dass dies durchaus angemessen ist:

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

int main()
{
    cout << "Main thread id: " << this_thread::get_id() << endl;
    for (int i = 0;  i < 2;  ++ i){
       cout << "------------------------" << endl;
       vector<future<void>> futures;
       for (int i = 0; i < 10; ++i)
       {
          this_thread::sleep_for(1 ms);
          auto fut = async([]{
                              this_thread::sleep_for(1 s);
                              cout << this_thread::get_id() << '\n';
                           });
          futures.push_back(move(fut));
       }
       for (auto &f : futures)
          f.wait();
    }

    cout << endl;
}

Main thread id: 140657228855104

140657228850944
140657220458240
140657212065536
140657203672832
140657195280128
140657186887424
140657178494720
140657170102016
140657161709312
140657153316608
------------------------
140657153316608
140657161709312
140657170102016
140657178494720
140657228850944
140657220458240
140657212065536
140657203672832
140657195280128
140657186887424

Sie können sehen, dass async für den zweiten Stapel von Aufträgen bereits erstellte Threads verwendet und keine neuen erstellt hat. Ich habe es also nicht zu Unrecht verwässert, denke ich.

 
Roman:

Es gibt auch eine Frage zum Einrichten eines Projekts für dll.
Wie kann ich ungenutzte Funktionen loswerden, die von den Compilern automatisch in die DLL-Abhängigkeit gezogen werden?

Bei mingw sollte die Option -static helfen , denn mit static wird kein Bild mehr erzeugt.

 

Härterer asynchroner Test

#include <future>
#include <iostream>
#include <vector>
#include <mutex>
#include <set>
using namespace std;

mutex mtx;
set<thread::id> id;
atomic<unsigned> atm{0};

int main()
{
   for (int i = 0;  i < 10000;  ++ i) {
      vector<future<void>> futures;
      for (int i = 0; i < 10; ++i) {
         auto fut = async(launch::async,[]{
                                           ++ atm;
                                           lock_guard<mutex> lck{mtx};
                                           id.insert( this_thread::get_id() );
                                        });
         futures.push_back(move(fut));
      }
   }

   cout << "executed " << atm << " tasks, by " << id.size() << " threads\n";
}
// cout: executed 100000 tasks, by 10 threads

Nun, ja, es funktioniert gut. Warum habe ich so schlecht von ihr gedacht? Wahrscheinlich eine krumme Implementierung zu Beginn von C++11 ...

SZY: aber ich sollte anmerken, dass das abnormal langsame async() mit lanch::async policy, wenn Sie es durch lanch::deferred ersetzen (+ warten auf die Beendigung des Jobs am Ende des ersten Zyklus), dann beginnt dieser einfache Test 30 mal schneller zu arbeiten !!! So viel zum Thema Multithreading )). Damit bleibt Platz für einen selbstgebauten Fadenpool, der meines Erachtens viel schneller als der Standardpool hergestellt werden kann.

 
Roman:

Es gibt auch eine Frage zum Einrichten eines Projekts für dll.
Wie wird man unbenutzte Funktionen los, die von Compilern automatisch in die DLL-Abhängigkeit gezogen werden?

Ich habe bereits verschiedene IDEs ausprobiert, und jede von ihnen zieht ihre eigene ungenutzte Funktion.
MSVS_2017 zieht sogar seine eigenen Zeitabhängigkeiten, die ich wohl nicht loswerde.

Nehmen Sie es als selbstverständlich hin und vergessen Sie es, oder vergessen Sie es.
Was und warum ist sie ein Ärgernis? Überlassen Sie den Unsinn den Nachbarn).
Hochsprachen sind so konzipiert, dass sich ein Programmierer nicht um Details kümmern muss. Das ist nicht die Sache des Zaren. Ja, und woher wissen Sie, was Sie brauchen und was nicht? Der Compiler weiß es am besten.
 
Vict:

Härterer asynchroner Test

Nun, ja, es funktioniert gut. Warum habe ich so schlecht von ihr gedacht? Wahrscheinlich eine krumme Implementierung zu Beginn von C++11 ...

SZY: aber ich sollte anmerken, dass das abnormal langsame async() mit lanch::async policy, wenn Sie es durch lanch::deferred ersetzen (+ warten auf die Beendigung des Jobs am Ende des ersten Zyklus), dann beginnt dieser einfache Test 30 mal schneller zu arbeiten !!! So viel zum Thema Multithreading )). Damit bleibt Platz für einen selbstgebauten Fadenpool, der meines Erachtens viel schneller als der Standardpool hergestellt werden kann.

Ich habe nicht bis zum Ende gelesen und beschlossen, Ihnen vorzuschlagen, mit der aufgeschobenen Flagge zu laufen ))))) Wenn ein solcher Test schneller abläuft, halte ich diese Art der Nutzung im Allgemeinen für vorteilhafter, warum also starre Grenzen setzen? Ich wollte mich nur für den Link zu Git bedanken, habe ihn mit Interesse verfolgt )) Mir hat gefallen, dass es zwei Versionen gibt - mit und ohne Boost.

Roman:

Eine weitere Frage bezog sich auf die Einrichtung des Projekts für die dll.
Wie kann ich ungenutzte Funktionen loswerden, die von Compilern automatisch in die DLL-Abhängigkeit gezogen werden?

Ich habe bereits verschiedene Entwicklungsumgebungen ausprobiert, und jede von ihnen zieht ihre eigene ungenutzte Funktion.
MSVS_2017 zieht sogar seine eigenen Zeitabhängigkeiten, die ich wohl nicht loswerde.
Deshalb habe ich verschiedene IDEs ausprobiert, aber auch diese ziehen ungenutzte Funktionen.
Wie wird man sie wieder los?

Wie kann man auf Schimpfwörter verzichten? Und ja, es ist überall anders. Nein, kein Stochern oder Stoßen ohne rantime )))) Sie haben noch nicht mit QT gearbeitet, da wird eine ganze Girlande von DLL-Würsten gezogen.


 
Andrei Novichkov:

Ich habe nicht bis zum Ende gelesen und beschlossen, Ihnen vorzuschlagen, dass Sie mit der aufgeschobenen Flagge )))) laufen.



Warum brauchen wir async() mit dem Flag deferred? Ich verstehe das wirklich nicht, können Sie das erklären?

 
Vict:

Warum brauchen wir async() mit dem Flag deferred? Ich verstehe das wirklich nicht, können Sie das erklären?

Warum lesen Sie nicht in der Dokumentation über die Flagge? Unter https://en.cppreference.com. Und Beispiele mit Diskussion auf stackoverflow.com. Ich nutze diese Informationsquellen in der Regel, und ich rate Ihnen, dies auch zu tun.

 
Andrei Novichkov:

Warum nicht in der Dokumentation über die Flagge lesen? Unter https://en.cppreference.com. Und Beispiele mit Diskussion auf stackoverflow.com. Ich nutze diese Informationsquellen in der Regel, und ich rate Ihnen, dies auch zu tun.

MSDN. Vollständige Dokumentation. Der Rest ist nur ergänzendes Material.