Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/155.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 避免在不同线程中执行未来时破坏对象_C++_C++11_Future - Fatal编程技术网

C++ 避免在不同线程中执行未来时破坏对象

C++ 避免在不同线程中执行未来时破坏对象,c++,c++11,future,C++,C++11,Future,想象一下以下情况: class A { public: folly::Future<folly::Unit> fooA(std::function<void()> callback); }; class B { public: void fooB() { a_->fooA([] { doSomethingCheap_(); }) /* Executed in thread 1 */ .via(exec_.get())

想象一下以下情况:

class A {
 public:
  folly::Future<folly::Unit> fooA(std::function<void()> callback);
};

class B {
 public:
  void fooB() {
    a_->fooA([] { doSomethingCheap_(); })  /* Executed in thread 1 */
        .via(exec_.get())
        .then([] { doSomethingExpensive_(); }) /* Executed in thread 2 */
  }
 private:
  std::shared_ptr<folly::Executor> exec_;
  std::shared_ptr<A> a_;

  void doSomethingCheap_();
  void doSomethingExpensive_();
};
A类{
公众:
folly::Future fooA(std::函数回调);
};
B类{
公众:
void fooB(){
在线程1中执行的一个->fooA([]{doSomethingCheap()})/**/
.via(exec_.get())
。然后在线程2中执行([]{dosomethingeexpensive_u()})/*操作*/
}
私人:
std::共享\u ptr exec;
std::共享的ptr a;
void doSomethingCheap_();
void dosothingexpensive_u2;;
};
如果在我们结束执行时,
doSomethingCheap_uz()
object
bb
将被销毁,那么我们将得到
segfault
。也许我们可以在
A类
中保持
弱ptr
,但当我们不仅要在
B类
中使用
A类
而且要在某些
C类
中使用
时,这种方法是不可扩展的


避免这种情况的最佳方法是什么?

我不熟悉愚蠢或您正在使用的同步机制,但似乎您可以使用一个互斥保护的布尔,捕获并传递给lambda调用dosomethingeexpensive-这将是一个“穷人的加入”。锁定互斥锁,然后将布尔值翻转为true。或者,您可以使用类似于absl::Notification的东西[因为我知道这一点]

#include "absl/synchronization/notification.h"

class A {
 public:
  folly::Future<folly::Unit> fooA(std::function<void()> callback);
};

class B {
 public:
  void fooB() {
    a_->fooA([] { doSomethingCheap_(); })  /* Executed in thread 1 */
        .via(exec_.get())
        .then([this] {
                  doSomethingExpensive_();
                  finished_.Notify();
               }) /* Executed in thread 2 */
    finished_.WaitForNotification();
  }
 private:
  std::shared_ptr<folly::Executor> exec_;
  std::shared_ptr<A> a_;
  absl::Notification finished_;

  void doSomethingCheap_();
  void doSomethingExpensive_();
};
#包括“absl/synchronization/notification.h”
甲级{
公众:
folly::Future fooA(std::函数回调);
};
B类{
公众:
void fooB(){
在线程1中执行的一个->fooA([]{doSomethingCheap()})/**/
.via(exec_.get())
.然后([这个]{
doSomethingExpensive_uz();
已完成。通知();
})/*在线程2中执行*/
已完成。WaitForNotification();
}
私人:
std::共享\u ptr exec;
std::共享的ptr a;
absl::通知已完成;
void doSomethingCheap_();
void dosothingexpensive_u2;;
};

最终,加入线程似乎是正确的选择,我只是不确定folly中暴露了什么。

我不熟悉folly或您正在使用的同步机制,但似乎您可以使用一个互斥保护的bool,捕获并传递给lambda调用doSomethingExpensive-这将是一个“可怜的人的加入”。锁定互斥锁,然后将bool翻转为true。或者,您可以使用类似于absl::Notification的东西[因为我知道这一点]

#include "absl/synchronization/notification.h"

class A {
 public:
  folly::Future<folly::Unit> fooA(std::function<void()> callback);
};

class B {
 public:
  void fooB() {
    a_->fooA([] { doSomethingCheap_(); })  /* Executed in thread 1 */
        .via(exec_.get())
        .then([this] {
                  doSomethingExpensive_();
                  finished_.Notify();
               }) /* Executed in thread 2 */
    finished_.WaitForNotification();
  }
 private:
  std::shared_ptr<folly::Executor> exec_;
  std::shared_ptr<A> a_;
  absl::Notification finished_;

  void doSomethingCheap_();
  void doSomethingExpensive_();
};
#包括“absl/synchronization/notification.h”
甲级{
公众:
folly::Future fooA(std::函数回调);
};
B类{
公众:
void fooB(){
在线程1中执行的一个->fooA([]{doSomethingCheap()})/**/
.via(exec_.get())
.然后([这个]{
doSomethingExpensive_uz();
已完成。通知();
})/*在线程2中执行*/
已完成。WaitForNotification();
}
私人:
std::共享\u ptr exec;
std::共享的ptr a;
absl::通知已完成;
void doSomethingCheap_();
void dosothingexpensive_u2;;
};

最终,加入线程似乎是正确的选择,我只是不确定愚蠢中暴露了什么。

表达式
doSomethingCheap()
dosomethingeexpensive()
的类型为void,无法传递给其他函数。@aschepler,如果你有这个想法,你能纠正我的代码吗?不太熟悉
std::function
,但为了举例而使用它。这就是executor的
makeKeepAlive
的目的吗?或者也许有一种很好的方法可以使用共享ptr来保持B的活力?不过我看不到。表达式
doSomethingCheap\(
dosomethingeexpensive\)
的类型为void,无法传递给其他函数。@aschepler,如果你有这个想法,你能纠正我的代码吗?不太熟悉
std::function
,但为了举例而使用它。这就是executor的
makeKeepAlive
的目的吗?或者也许有一种很好的方法可以使用共享ptr来保持B的活力?不过我看不到。