MQL中的异步和多线程编程 - 页 34

 
Andrei Novichkov:
但我想知道是否有一些任务真的需要线程池?不仅仅是--创建一个线程,忘记它,等待它用完,而恰恰是一个池子,像威廉姆斯描述的那样?如果我没记错的话,那里似乎是一个自动取款机的例子--什么任务可以证明这样的奇迹柔道?我还想不出这样的任务。你为什么不看看ThreadPool,那里的一切都已经完成了,有文档和例子。

说实话,到目前为止,我还没有看到std::async和线程池之间有什么意义,只是std::async会自动为手头的任务创建和删除一个线程。
而要使用线程池,你需要事先知道程序中使用的线程数,并为池子明确设置这个数字。
事实证明,就线程数量而言,线程池是静态的,尽管这可能不是事实,我不能断言。
但在Williams的书中,他说当有非常多的任务要在std::thread中运行时,推荐使用线程池。
而这也许并不适用于std::async,我还没有完全掌握其含义。
而异步性在网络解决方案中的需求非常大,多符号策略,以及对于加载的计算也很有用。
但是,由于标准中有std::async和std::promise,我认为没有必要创建一个线程池。

 

还有一个关于为dll设置项目 的问题。
如何摆脱未使用的函数,这些函数被编译器自动拉入dll依赖关系中?

我已经尝试了不同的开发环境,每个环境都拉出了自己的未用功能。
MSVS_2017甚至拉出了自己的运行时依赖,我想我无法摆脱这些依赖。
因此,我尝试了不同的IDE,但它们也拉出了未使用的功能。
如何摆脱它们?

附加的文件:
 
Roman:

说实话,我自己并没有发现std::async和线程池之间有什么意义,只是std::async会自动为手头的任务创建和删除一个线程。
而要使用线程池,你需要事先知道程序中使用的线程数,并为池子明确设置这个数字。
事实证明,就线程数量而言,线程池是静态的,尽管这可能不是事实,我不能断言。
但在Williams的书中,他说当有很多任务要在std::thread中运行时,推荐使用线程池。
而这也许并不适用于std::async,我还没有完全掌握其含义。
而异步性在网络解决方案中的需求非常大,多符号策略,以及对于加载的计算也很有用。
但是,由于标准中有std::async和std::promise,我认为没有必要创建一个线程池。

所以,异步的主要意义在于使用线程池,摆脱线程创建/删除的开销,如果异步不能做到这一点,那么它就毫无价值。

嗯,实际上,我对async想得太坏了,显然。一个简单的测试表明它是一个相当充分的东西。

#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

你可以看到,对于第二批作业,async使用了以前创建的线程,没有创建新线程。所以我并不是当之无愧地冲淡了它,我想。

 
Roman:

还有一个关于为dll设置项目的问题。
我怎样才能摆脱那些被编译器自动拉入dll依赖关系的未使用的函数?

对于mingw来说,选项-static应该 对静态有帮助 ,它会停止生成图片。

 

更严厉的异步测试

#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

嗯,是的,它工作得很好。为什么我把它想得那么坏?可能是在c++11的黎明时分的一个歪曲的实现 ...

SZY: 但是我应该注意,用lanch::async策略的async()异常缓慢,如果你用lanch::deferred(+在第一个周期结束时等待工作完成)来代替它,那么这个简单的测试开始工作时就会快30倍!!。这么多的多线程)))。因此,这为自制线程池留下了空间,在我看来,它可以比标准线程池快得多。

 
Roman:

还有一个关于为dll设置项目的问题。
如何摆脱未使用的函数,这些函数被编译器自动拉入dll依赖关系中?

我已经尝试了不同的IDE,每一个都拉出了自己的未用功能。
MSVS_2017甚至拉出了自己的时间依赖,我想我无法摆脱它。

认为这是理所当然的,忘记它,或忘记它。
是什么,为什么会造成扰民?把胡言乱语留给邻居)。
高级语言的创建是为了让程序员不关心细节。这不是沙皇的事。是的,你怎么知道你需要什么,你不需要什么。编译器最了解。
 
Vict:

更严厉的异步测试

嗯,是的,它工作得很好。为什么我把它想得那么坏?可能是在c++11的黎明时分的一个歪曲的实现 ...

SZY: 但是我应该注意,用lanch::async策略的async()异常缓慢,如果你用lanch::deferred(+在第一个周期结束时等待工作完成)来代替它,那么这个简单的测试开始工作时就会快30倍!!。这么多的多线程))。因此,这为自制线程池留下了空间,在我看来,它可以比标准线程池快得多。

我没有读到最后,决定建议你带着推迟的旗帜运行)))))。有道理,如果这样的测试运行得更快,我一般认为这样的使用方式是比较好的,为什么要设置硬性限制。我只想说,感谢你提供的Git的链接,我很感兴趣地看了它))我喜欢有两个版本--有升压和无升压。

罗马 人。

另一个问题是关于为dll设置项目的问题。
我怎样才能摆脱未使用的函数,这些函数被编译器自动拉入dll依赖关系中?

我已经尝试了不同的开发环境,每个环境都拉出了自己的未用功能。
MSVS_2017甚至拉出了自己的时间依赖,我想我无法摆脱它。
因此,我尝试了不同的IDE,但它们也拉出了未使用的功能。
如何摆脱它们?

不咆哮怎么能行?是的,各地的情况都不一样。不,没有rantime,就没有推拉))))。你还没有用过QT,那是拉出一整串DLL香肠的地方。


 
Andrei Novichkov:

我没有读到最后,决定建议你带着推迟的标志运行))))。



为什么我们需要带有递延标志的async()?我真的不明白,你能解释一下吗?

 
Vict:

为什么我们需要带有递延标志的async()?我真的不明白,你能解释一下吗?

事实上,你为什么不在文档中阅读关于该标志的内容?在https://en.cppreference.com 。以及在stackoverflow.com上有讨论的例子。我通常使用这些信息来源,我建议你也这样做。

 
Andrei Novichkov:

为什么不在文档中实际阅读关于该标志的内容?在https://en.cppreference.com 。以及在stackoverflow.com上有讨论的例子。我通常使用这些信息来源,我建议你也这样做。

MSDN。完整的文件。其余的只是补充材料。