Programación asíncrona y multihilo en MQL - página 34

 
Andrei Novichkov:
Pero me pregunto si hay tareas que realmente requieren la agrupación de hilos. No sólo - crear un hilo, olvidarlo y esperar a que se agote, sino exactamente un pool, como lo describe Williams? Parece ser un ejemplo de cajero automático, si no me equivoco: ¿qué tarea podría justificar semejante milagro? Todavía no se me ocurre tal tarea. Y por qué no te fijas realmente en ThreadPool donde ya está todo hecho, hay documentación y ejemplos.

Para ser honesto, hasta ahora no he visto mucho sentido entrestd::async y el pool de hilos, excepto questd::async crea y elimina automáticamente un hilo para la tarea en cuestión.
Y para utilizar el pool de hilos, es necesario conocer de antemano el número de hilos utilizados en el programa, y establecer este número para el pool explícitamente.
Resulta que la agrupación de hilos es estática en cuanto al número de hilos, aunque puede que no sea así, no puedo afirmarlo.
Pero en el libro de Williams, él dice que la agrupación de hilos se recomienda cuando hay muchas tareas para ejecutar en std::thread.
Y tal vez esto no se aplique astd::async, todavía no he entendido bien el significado.
Y la asincronía es muy demandada en las soluciones de red, y las estrategias multisímbolo, y para los cálculos cargados también es útil.
Pero teniendostd::async y std::promise en el estándar, creo que no hay necesidad de crear un pool de hilos.

 

También hay una pregunta sobre la creación de un proyecto para dll.
¿Cómo deshacerse de las funciones no utilizadas que los compiladores introducen automáticamente en la dependencia de la dll?

Ya he probado diferentes entornos de desarrollo, y cada uno de ellos saca su propia función no utilizada.
MSVS_2017 incluso saca sus propias dependencias de tiempo de ejecución, de las que supongo que no puedo deshacerme.
Por lo tanto, he probado diferentes IDEs, pero también tiran de funciones no utilizadas.
¿Cómo deshacerse de ellos?

Archivos adjuntos:
 
Roman:

Para ser honesto, yo mismo no he encontrado mucho sentido entre std::async y thread pooling, excepto que std::async crea y elimina automáticamente un hilo para la tarea en cuestión.
Y para utilizar el pool de hilos, es necesario conocer de antemano el número de hilos utilizados en el programa, y establecer este número para el pool explícitamente.
Resulta que la agrupación de hilos es estática en cuanto al número de hilos, aunque puede que no sea así, no puedo afirmarlo.
Pero en el libro de Williams, dice que la agrupación de hilos se recomienda cuando hay muchas tareas que ejecutar en std::thread.
Y tal vez esto no se aplique astd::async, todavía no he entendido bien el significado.
Y la asincronía es muy demandada en las soluciones de red, y las estrategias multisímbolo, y para los cálculos cargados también es útil.
Pero teniendostd::async y std::promise en el estándar, creo que no hay necesidad de crear un pool de hilos.

Así que el punto principal de async es usar el pool de hilos, deshacerse de la sobrecarga de creación/borrado de hilos, si async no hace eso, entonces no vale nada.

Bueno, en realidad, estaba pensando demasiado mal sobre async, aparentemente. Una simple prueba demuestra que es algo bastante adecuado:

#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

Puedes ver que para el segundo lote de trabajos async utilizó hilos previamente creados y no creó otros nuevos. Así que no lo estaba aguando merecidamente, supongo.

 
Roman:

También hay una pregunta sobre la creación de un proyecto para dll.
¿Cómo puedo deshacerme de las funciones no utilizadas que los compiladores introducen automáticamente en la dependencia de la dll?

Para mingw la opción -static debería ayudar con static deja de generar pic

 

Prueba asíncrona más dura

#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

Bueno, sí, funciona bien. ¿Por qué me pareció tan mal? Probablemente una implementación torcida en los albores de c++11 ...

¡¡¡SZY: pero debo notar que la anormalmente lenta async() con la política lanch::async, si la reemplazas con lanch::deferred (+ esperar la finalización del trabajo al final del primer ciclo), entonces esta simple prueba comienza a funcionar 30 veces más rápido !!! Esto en cuanto al multihilo )). Así que eso deja espacio para una piscina de hilo casera, me parece que se puede hacer mucho más rápido que el estándar.

 
Roman:

También hay una pregunta sobre la creación de un proyecto para dll.
¿Cómo deshacerse de las funciones no utilizadas que los compiladores introducen automáticamente en la dependencia de la dll?

Ya he probado diferentes IDEs, y cada uno de ellos saca su propia función no utilizada.
MSVS_2017 incluso saca sus propias dependencias de tiempo, de las que supongo que no puedo deshacerme.

Darlo por hecho y olvidarlo, u olvidarlo.
¿Qué y por qué es una molestia? Deja las tonterías para los vecinos).
Los lenguajes de alto nivel se crean para que un programador no se preocupe por los detalles. No es un asunto de zares. Sí, y cómo sabes lo que necesitas y lo que no. El compilador sabe más.
 
Vict:

Prueba asíncrona más dura

Bueno, sí, funciona bien. ¿Por qué me pareció tan mal? Probablemente una implementación torcida en los albores de c++11 ...

¡¡¡SZY: pero debo notar que la anormalmente lenta async() con la política lanch::async, si la reemplazas con lanch::deferred (+ esperar la finalización del trabajo al final del primer ciclo), entonces esta simple prueba comienza a funcionar 30 veces más rápido !!! Esto en cuanto al multihilo )). Así que eso deja espacio para una piscina de hilo casera, me parece que se puede hacer mucho más rápido que el estándar.

No he leído hasta el final y he decidido sugerirte que corras con la bandera del diferido ))))) Tiene sentido, si una prueba de este tipo se ejecuta más rápido, en general creo que es preferible esta forma de utilizarla, por qué poner límites rígidos. Sólo quería dar las gracias por el enlace a Git, lo he visto con interés )) Me ha gustado que haya dos versiones: con y sin impulso.

Romano:

También surgió otra pregunta sobre la configuración del proyecto para el dll.
¿Cómo puedo deshacerme de las funciones no utilizadas, que los compiladores introducen automáticamente en la dependencia de la dll?

Ya he probado diferentes entornos de desarrollo, y cada uno de ellos saca su propia función no utilizada.
MSVS_2017 incluso saca sus propias dependencias de tiempo, de las que supongo que no puedo deshacerme.
Por lo tanto, he probado diferentes IDEs, pero también tiran de funciones no utilizadas.
¿Cómo deshacerse de ellos?

¿Cómo se puede hacer sin despotricar? Y sí, es diferente en todas partes. No, sin rantime no hay empuje ni tirón )))) Todavía no has trabajado con QT, ahí es donde se tira toda una guirnalda de salchichas DLL.


 
Andrei Novichkov:

No leí hasta el final y decidí sugerirle que corriera con la bandera diferida ))))



¿Por qué necesitamos async() con la bandera diferida? Realmente no lo entiendo, ¿puede explicarlo?

 
Vict:

¿Por qué necesitamos async() con la bandera diferida? Realmente no lo entiendo, ¿puede explicarlo?

De hecho, ¿por qué no lees sobre la bandera en la documentación? En https://en.cppreference.com . Y ejemplos con discusión en stackoverflow.com. Yo suelo utilizar estas fuentes de información, y te aconsejo que hagas lo mismo.

 
Andrei Novichkov:

¿Por qué no leer realmente sobre la bandera en la documentación? En https://en.cppreference.com . Y ejemplos con discusión en stackoverflow.com. Yo suelo utilizar estas fuentes de información, y te aconsejo que hagas lo mismo.

MSDN. Documentación completa. El resto es material complementario.