Asynchronous and multi-threaded programming in MQL - page 34

 
Andrei Novichkov:
But I wonder if there are tasks that really require thread pooling? Not just - create a thread, forget it and wait for it to run out, but exactly a pool, like Williams describes it? It seems to be an example of an ATM there, if I'm not mistaken - what task could justify such a miracle judo? I can't think of such a task yet. And why don't you really look at ThreadPool where everything is already done, there is documentation and examples.

To be honest, so far I haven't seen much sense betweenstd::async and thread pool, except thatstd::async automatically creates and deletes a thread for the task at hand.
And to use thread pooling, you need to know in advance the number of threads used in the program, and set this number for the pool explicitly.
It turns out that the thread pooling is static in terms of number of threads, although this may not be the case, I can not assert.
But in Williams' book, he says that thread pooling is recommended when there are very many tasks to run in std::thread.
And maybe this doesn't apply tostd::async, I haven't fully grasped the meaning yet.
And asynchrony is very much in demand in networking solutions, and multisymbol strategies, and for loaded calculations is also useful.
But havingstd::async and std::promise in the standard, I think there is no need to create a thread pool.

 

There's also a question about setting up a project for dll.
How to get rid of unused functions, which are automatically pulled into dll dependency by compilers?

I have already tried different development environments, and each of them pulls its own unused function.
MSVS_2017 even pulls its own runtime dependencies, which I guess I cannot get rid of.
Therefore I've tried different IDEs, but they also pull unused functions.
How to get rid of them?

 
Roman:

To be honest, I haven't caught much sense betweenstd::async and thread pooling myself, except that std::async automatically creates and deletes a thread for the task at hand.
And to use thread pooling, you need to know in advance the number of threads used in the program, and set this number for the pool explicitly.
It turns out that the thread pooling is static in terms of number of threads, although this may not be the case, I can not assert.
But in Williams' book, he says that thread pooling is recommended when there are a lot of tasks to run in std::thread.
And maybe this doesn't apply tostd::async, I haven't fully grasped the meaning yet.
And asynchrony is very much in demand in networking solutions, and multisymbol strategies, and for loaded calculations is also useful.
But havingstd::async and std::promise in the standard, I think there is no need to create a thread pool.

So the main point of async is to use thread pool, get rid of thread creation/deletion overhead, if async doesn't do that, then it's worthless.

Well, actually, I was thinking too badly about async, apparently. A simple test shows it as a quite adequate thing:

#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

You can see that for the second batch of jobs async used previously created threads and didn't create new ones. So I wasn't exactly watering it down deservedly, I guess.

 
Roman:

There's also a question about setting up a project for dll.
How can I get rid of unused functions that are automatically pulled into the dll dependency by the compilers?

For mingw the option -static should help with static it stops generating pic

 

Tougher async 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

Well, yeah, it works fine. Why did I think so badly of it? Probably a crooked implementation at the dawn of c++11 ...

SZY: but I should note that abnormally slow async() with lanch::async policy, if you replace it with lanch::deferred (+ wait for job completion at the end of first cycle), then this simple test starts working 30 times faster !!! So much for multithreading )). So that leaves room for a homemade thread pool, it seems to me that it can be made much faster than the standard one.

 
Roman:

There's also a question about setting up a project for dll.
How to get rid of unused functions, which are automatically pulled into dll dependency by compilers?

I have already tried different IDEs, and each of them pulls its own unused function.
MSVS_2017 even pulls its own time dependencies, which I guess I cannot get rid of.

Take it for granted and forget it, or forget it.
What and why is it a nuisance? Leave the nonsense to the neighbours).
High-level languages are created so that a programmer doesn't care about details. It's not a tsar's business. Yes, and how do you know what you need and what you don't need. The compiler knows best.
 
Vict:

Tougher async test

Well, yeah, it works fine. Why did I think so badly of it? Probably a crooked implementation at the dawn of c++11 ...

SZY: but I should note that abnormally slow async() with lanch::async policy, if you replace it with lanch::deferred (+ wait for job completion at the end of first cycle), then this simple test starts working 30 times faster !!! So much for multithreading )). So that leaves room for a homemade thread pool, it seems to me that it can be made much faster than the standard one.

I didn't read to the end and decided to suggest you run with the deferred flag ))))) Makes sense, if such a test runs faster, I generally think this way of using it is preferable, why put rigid limits. Just wanted to say thanks for your link to Git, watched it with interest )) I liked that there are two versions - with and without boost.

Roman:

Another question came up about setting up the project for the dll.
How can I get rid of unused functions, which are automatically pulled into dll dependency by compilers?

I've already tried different development environments, and each of them pulls its own unused function.
MSVS_2017 even pulls its own time dependencies, which I guess I cannot get rid of.
Therefore I've tried different IDEs, but they also pull unused functions.
How to get rid of them?

How can you do without ranting? And yes, it's different everywhere. No, without rantime there's no pushing or pulling )))) You haven't worked with QT yet, that's where a whole garland of DLL sausages is pulled.


 
Andrei Novichkov:

I didn't read to the end and decided to suggest that you run with the deferred flag ))))



Why do we need async() with the deferred flag? I really don't understand, can you explain?

 
Vict:

Why do we need async() with the deferred flag? I really don't understand, can you explain?

In fact, why don't you read about the flag in the documentation? At https://en.cppreference.com . And examples with discussion on stackoverflow.com. I usually use these sources of information, and I advise you to do the same.

 
Andrei Novichkov:

Why not actually read about the flag in the documentation? At https://en.cppreference.com . And examples with discussion on stackoverflow.com. I usually use these sources of information, and I advise you to do the same.

MSDN. Full documentation. The rest is just supplementary material.
Reason: