MQL中的异步和多线程编程 - 页 36 1...293031323334353637383940 新评论 Roman 2019.08.03 14:18 #351 Vict: 我想到的唯一合理的解释是手动控制池中运行的线程数量(如果我们不相信默认的async|deferred)--例如,如果我们看到系统负载很重,就重新发送带有async标志的作业,延迟发送。 总的来说,我对async()的迟钝有些失望,我将创建自己的轻量级线程池,在我看来,它将快得多。 书中描述了默认的async|deferred模式,因此如果没有足够的物理资源,任务不会创建新的线程,而是在主线程中执行,将其阻塞。 而且你应该时刻注意默认模式下主线程可能被锁定的情况,因为大多数时候你需要的解决方案是不要阻塞主线程。 也就是说,默认模式会根据物理资源(即处理器)的负载自动切换到哪里执行任务。 出于这个原因,如果我们确信物理资源不会被超载,我们最好明确指定标志std::launch::async。 但如果你溢出了现代处理器的物理资源,你将不得不寻找这样的计算,以发挥其全部潜力 )) 关于速度我不能说什么,因为我还在研究这个理论 )) [删除] 2019.08.03 14:30 #352 Roman: 所以,如果我们确定物理资源不会被溢出,最好是明确指定标志std::launch::async。 而要溢出现代处理器的物理资源,需要很长的时间来找到这样的计算方法来选择所有潜在的))。 处理器可以承受更多的线程,但操作系统的能力更有可能成为瓶颈。好吧,它不能无休止地繁殖线程,迟早async(launch::async, ...)会遇到一个被抛出的异常。 Roman 2019.08.03 14:46 #353 Vict: 处理器甚至可以承受大量的线程,但操作系统的能力更有可能成为瓶颈。好吧,它不能无休止地繁殖线程,迟早async(launch::async, ...)会遇到一个被抛出的异常。 是的,总是有一个物理限制,但在我们的任务中,不太可能超过这个限制,为mt5。 另外,async和future在它们的返回值中,如果出现异常,无论我们如何获得这个值,通过lambda函数、ref()或.get()都会返回。 而std::thread在其返回值中不能返回异常。 [删除] 2019.08.03 15:29 #354 Roman: 是的,总是有一个物理限制,但在我们对mt5的任务中,不太可能超过这个限制。 另外,async和future在它们的返回值中,如果出现异常,无论我们如何获得这个值,通过lamda函数、ref()或.get()都会返回。 而std::thread在其返回值中不能返回异常。 我认为你不应该对async感到太兴奋。这似乎是为了方便而做的,但所有这些东西似乎真的击中了性能。这不是由一个加一。 而返回值中的std::thread不能返回异常。 这并不总是必要的。但如果你这样做,就会多出十几行(尽管它的工作速度会更快--没有所有的分配在堆里)。 [删除] 2019.08.03 16:21 #355 Vict: 但如果你不得不这样做,那就是多了十几行(虽然它的工作速度会更快--没有堆积的所有分配)。 以便不至于没有事实根据。 #include <thread> #include <future> #include <iostream> #include <chrono> using namespace std; template <typename T> void thread_fn(T &&task) {task(0);} int main() { packaged_task<int(int)> task{ [](int i){this_thread::sleep_for(3 s); return i==0?throw 0: i;} }; auto f = task.get_future(); thread t{thread_fn<decltype(task)>, move(task)}; t.detach(); try { cout << f.get() << endl; }catch(...) { cout << "exception caught" << endl; } return 0; } 甚至不需要一打。是的,你可以做更多的低级别的事情,而不需要所有的packaged_task和future的东西,但这个想法是,抛出异常并不是一些超级异步的事情,线程绝对没有什么。 Andrei Novichkov 2019.08.03 18:03 #356 也许,从实用的角度来看,有时值得远离所有这些垫子,记住Windows的api--CreateThread、同步原语、互锁函数。同样,也有。当然,当你为风写的时候。为什么要把事情复杂化,因为MT4|MT5没有这么复杂的任务,需要延迟计算,集合等等。 Yuriy Asaulenko 2019.08.03 18:16 #357 Andrei Novichkov: 既然MT4|MT5没有复杂的任务需要延迟计算、资金池等,为什么还要把事情复杂化? 实际上是有任务的。MT不具备这种能力。在这里,各种各样的池子真的没有必要。标准的多线程解决方案,如果应用正确,就足够了。 Andrei Novichkov 2019.08.03 18:46 #358 Yuriy Asaulenko: 实际上,挑战是存在的。没有MT的可能性。 在这里,各种各样的池子真的没有必要。标准的多线程解决方案,如果应用正确,就足够了。 这就是我的意思。 [删除] 2019.08.04 12:06 #359 伙计们,我在分享我的研究。 我在膝盖上写了自己的线池。我应该注意到,这是一个相当实用的版本,你可以传递任何带有任何参数的函数,作为对未来的回应,也就是说,所有以捕获异常和等待终止为形式的plushkas都是可用的。而且它和https://www.mql5.com/ru/forum/318593/page34#comment_12700601 一样好。 #include <future> #include <iostream> #include <vector> #include <mutex> #include <set> mutex mtx; set<thread::id> id; atomic<unsigned> atm{0}; int main() { Thread_pool p{10}; for (int i = 0; i < 10000; ++ i) { vector<future<void>> futures; for (int i = 0; i < 10; ++i) { auto fut = p.push([]{ ++ 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"; } 我不知道是谁在什么状态下写了std::async,但我膝盖上开发的东西比标准的快4倍(有10个工作线程)。增加线程数超过内核数只会使我的速度变慢。在池子大小==核心数(2)的情况下,async输了大约30倍。所以,事情就是这样。 如果我想建立线程池,肯定不会是标准的异步))。 Roman 2019.08.04 16:03 #360 Vict: 伙计们,我在分享我的研究。 我在膝盖上写了自己的线池。我应该注意到,这是一个相当实用的版本,你可以传递任何带有任何参数的函数,作为对未来的回应,也就是说,所有以捕获异常和等待终止为形式的plushkas都是可用的。而我用的也是那里https://www.mql5.com/ru/forum/318593/page34#comment_12700601。 我不知道是谁在什么状态下写了std::async,但我膝盖上开发的东西比标准的快4倍(有10个工作线程)。增加线程数超过内核数只会使我的速度变慢。在池子大小==核心数(2)的情况下,async输了大约30倍。所以,事情就是这样。 如果我想建立线程池,肯定不会是标准的异步))。 谢谢你的研究。这是一个很好的例子,是值得思考和学习的地方。 但从我们的一般性讨论中,我们大多数人得出的结论是,流水池并不是真的需要。 在我的情况下,这是肯定的,因为我已经意识到池子里的线程数量是静态的,所以它对我不起作用。 但是,是的,当我需要一个游泳池时,你的例子将是恰到好处的。谢谢你展示的例子。 我仍然在掌握它的窍门 )) 1...293031323334353637383940 新评论 您错过了交易机会: 免费交易应用程序 8,000+信号可供复制 探索金融市场的经济新闻 注册 登录 拉丁字符(不带空格) 密码将被发送至该邮箱 发生错误 使用 Google 登录 您同意网站政策和使用条款 如果您没有帐号,请注册 可以使用cookies登录MQL5.com网站。 请在您的浏览器中启用必要的设置,否则您将无法登录。 忘记您的登录名/密码? 使用 Google 登录
我想到的唯一合理的解释是手动控制池中运行的线程数量(如果我们不相信默认的async|deferred)--例如,如果我们看到系统负载很重,就重新发送带有async标志的作业,延迟发送。
总的来说,我对async()的迟钝有些失望,我将创建自己的轻量级线程池,在我看来,它将快得多。
书中描述了默认的async|deferred模式,因此如果没有足够的物理资源,任务不会创建新的线程,而是在主线程中执行,将其阻塞。
而且你应该时刻注意默认模式下主线程可能被锁定的情况,因为大多数时候你需要的解决方案是不要阻塞主线程。
也就是说,默认模式会根据物理资源(即处理器)的负载自动切换到哪里执行任务。
出于这个原因,如果我们确信物理资源不会被超载,我们最好明确指定标志std::launch::async。
但如果你溢出了现代处理器的物理资源,你将不得不寻找这样的计算,以发挥其全部潜力 ))
关于速度我不能说什么,因为我还在研究这个理论 ))
所以,如果我们确定物理资源不会被溢出,最好是明确指定标志std::launch::async。
而要溢出现代处理器的物理资源,需要很长的时间来找到这样的计算方法来选择所有潜在的))。
处理器可以承受更多的线程,但操作系统的能力更有可能成为瓶颈。好吧,它不能无休止地繁殖线程,迟早async(launch::async, ...)会遇到一个被抛出的异常。
处理器甚至可以承受大量的线程,但操作系统的能力更有可能成为瓶颈。好吧,它不能无休止地繁殖线程,迟早async(launch::async, ...)会遇到一个被抛出的异常。
是的,总是有一个物理限制,但在我们的任务中,不太可能超过这个限制,为mt5。
另外,async和future在它们的返回值中,如果出现异常,无论我们如何获得这个值,通过lambda函数、ref()或.get()都会返回。
而std::thread在其返回值中不能返回异常。
是的,总是有一个物理限制,但在我们对mt5的任务中,不太可能超过这个限制。
另外,async和future在它们的返回值中,如果出现异常,无论我们如何获得这个值,通过lamda函数、ref()或.get()都会返回。
而std::thread在其返回值中不能返回异常。
我认为你不应该对async感到太兴奋。这似乎是为了方便而做的,但所有这些东西似乎真的击中了性能。这不是由一个加一。
而返回值中的std::thread不能返回异常。
但如果你不得不这样做,那就是多了十几行(虽然它的工作速度会更快--没有堆积的所有分配)。
以便不至于没有事实根据。
甚至不需要一打。是的,你可以做更多的低级别的事情,而不需要所有的packaged_task和future的东西,但这个想法是,抛出异常并不是一些超级异步的事情,线程绝对没有什么。
既然MT4|MT5没有复杂的任务需要延迟计算、资金池等,为什么还要把事情复杂化?
实际上,挑战是存在的。没有MT的可能性。
伙计们,我在分享我的研究。
我在膝盖上写了自己的线池。我应该注意到,这是一个相当实用的版本,你可以传递任何带有任何参数的函数,作为对未来的回应,也就是说,所有以捕获异常和等待终止为形式的plushkas都是可用的。而且它和https://www.mql5.com/ru/forum/318593/page34#comment_12700601 一样好。
我不知道是谁在什么状态下写了std::async,但我膝盖上开发的东西比标准的快4倍(有10个工作线程)。增加线程数超过内核数只会使我的速度变慢。在池子大小==核心数(2)的情况下,async输了大约30倍。所以,事情就是这样。
如果我想建立线程池,肯定不会是标准的异步))。
伙计们,我在分享我的研究。
我在膝盖上写了自己的线池。我应该注意到,这是一个相当实用的版本,你可以传递任何带有任何参数的函数,作为对未来的回应,也就是说,所有以捕获异常和等待终止为形式的plushkas都是可用的。而我用的也是那里https://www.mql5.com/ru/forum/318593/page34#comment_12700601。
我不知道是谁在什么状态下写了std::async,但我膝盖上开发的东西比标准的快4倍(有10个工作线程)。增加线程数超过内核数只会使我的速度变慢。在池子大小==核心数(2)的情况下,async输了大约30倍。所以,事情就是这样。
如果我想建立线程池,肯定不会是标准的异步))。
谢谢你的研究。这是一个很好的例子,是值得思考和学习的地方。
但从我们的一般性讨论中,我们大多数人得出的结论是,流水池并不是真的需要。
在我的情况下,这是肯定的,因为我已经意识到池子里的线程数量是静态的,所以它对我不起作用。
但是,是的,当我需要一个游泳池时,你的例子将是恰到好处的。谢谢你展示的例子。
我仍然在掌握它的窍门 ))