异步任务已经完成时如何调用函数?
how to call a function when an asynchronous task is already done?
我有一套类是这样的:
class A {
public:
std::unique_ptr<B> b;
void triggerAsynchronously() {
// this work is submitted to a queue.
b->getC()->signalAsync();
}
};
class B {
public:
std::shared_ptr<C> c;
std::shared_ptr<C> getC() const {
return c;
}
void doSomethingWithSignalFromClassC() {}
};
class C {
public:
void signalAsync() {
// This function is submitted to a queue, and wait until its turn to be executed.
// I want to trigger A::b::doSomethingWithSignalFromC() once this function is done (aka end of this block)
}
}
C::signalAsync()
由 A::triggerSignalCAsynchronously()
触发。注意A::triggerSignalCAsynchronously()
returns提交作品到队列后立即执行,但C::signalAsync()
并没有立即执行。一旦 C::signalAsync()
被执行并完成它的工作,它应该通知 A::b::doSomethingWithSignalFromClassC()
.
我的问题是:当C::signalAsync()
已经完成时如何通知B
?从A
,我们可以得到一个shared_pointer<C>
。因此,自然的做法是将weak_ptr<B>
存储在C
中。但是,这不起作用,因为 b
是一个唯一指针。我还考虑在 C 中存储 B
的原始指针,但这似乎违背了 unique_ptr
设计。
此外,在 C
中存储指向 A
的原始指针似乎是错误的:
class A {
void setA() {
b->getC()->setA(this);
}
}
我感觉我的设计有问题。如果是你来解决这个问题,你会尝试哪些方向?
您需要非常准确地说明您的要求。你说
Once C::signalAsync() is executed and done with its work, it should notify A::b::doSomethingWithSignalFromClassC()
'Notify' 暗示线程正在某处等待被唤醒做某事 - 这很复杂
但您也可以表示,我希望 singalAsync 调用 B 实例上的方法。这很简单。
不知道这些调用的限制(你不会全部调用还是库中有一些你无法更改等)使它变得更难。
这是我要为回调案例做的事情
class C {
std::shared_ptr<B> callback_;
public:
C(std::shared_ptr<B> &cb){
callback_ = cb;
}
void signalAsync() {
// noodle noodle noodle
callback_->doSomethingWithSignalFromClassC();
}
}
即当我构造一个 C 对象时告诉它要回调的对象。
或者,您可以将其作为参数传递给 signalAsync,但也许那是不可能的
另一个想法是在构造函数中传递 std::function
,这样您就不必硬编码在 signalAsync
结束时调用的方法
根据 pm100 的 answer,std::function
的用法确实有效。我想写下我最后做了什么,以防万一有人需要它。更详细一点,在我的例子中,C
的 header 文件不能包含 B
的 header 文件,因为 B
已经包含 C
在其 header 中(前向声明无效)。 C
也不能包含 A
,因为 A
被设计为一个实现 class(指向实现的指针);因此,A
header 位于 src
文件夹内,不应包含在任何地方(A.cc
除外)
我最后做了什么:
class A {
public:
std::unique_ptr<B> b;
void triggerAsynchronously() {
// this work is submitted to a queue.
b->getC()->signalAsync();
}
void setFunctionToC() {
// This happens before triggerAsynchronously()
auto do_something_when_finished = [&b = b]() {
b->doSomethingWithSignalFromClassC();
}
b->getC()->setFunctionToC(do_something_when_finished);
}
};
class C {
std::function<void()> call_on_finished;
public:
void setFunctionToC(std::function<void()> f) {
call_on_finished = f;
}
void signalAsync() {
// This function is submitted to a queue, and wait until its turn to be executed.
// I want to trigger A::b::doSomethingWithSignalFromC() once this function is done (aka end of this block)
call_on_finished();
}
}
我有一套类是这样的:
class A {
public:
std::unique_ptr<B> b;
void triggerAsynchronously() {
// this work is submitted to a queue.
b->getC()->signalAsync();
}
};
class B {
public:
std::shared_ptr<C> c;
std::shared_ptr<C> getC() const {
return c;
}
void doSomethingWithSignalFromClassC() {}
};
class C {
public:
void signalAsync() {
// This function is submitted to a queue, and wait until its turn to be executed.
// I want to trigger A::b::doSomethingWithSignalFromC() once this function is done (aka end of this block)
}
}
C::signalAsync()
由 A::triggerSignalCAsynchronously()
触发。注意A::triggerSignalCAsynchronously()
returns提交作品到队列后立即执行,但C::signalAsync()
并没有立即执行。一旦 C::signalAsync()
被执行并完成它的工作,它应该通知 A::b::doSomethingWithSignalFromClassC()
.
我的问题是:当C::signalAsync()
已经完成时如何通知B
?从A
,我们可以得到一个shared_pointer<C>
。因此,自然的做法是将weak_ptr<B>
存储在C
中。但是,这不起作用,因为 b
是一个唯一指针。我还考虑在 C 中存储 B
的原始指针,但这似乎违背了 unique_ptr
设计。
此外,在 C
中存储指向 A
的原始指针似乎是错误的:
class A {
void setA() {
b->getC()->setA(this);
}
}
我感觉我的设计有问题。如果是你来解决这个问题,你会尝试哪些方向?
您需要非常准确地说明您的要求。你说
Once C::signalAsync() is executed and done with its work, it should notify A::b::doSomethingWithSignalFromClassC()
'Notify' 暗示线程正在某处等待被唤醒做某事 - 这很复杂
但您也可以表示,我希望 singalAsync 调用 B 实例上的方法。这很简单。
不知道这些调用的限制(你不会全部调用还是库中有一些你无法更改等)使它变得更难。
这是我要为回调案例做的事情
class C {
std::shared_ptr<B> callback_;
public:
C(std::shared_ptr<B> &cb){
callback_ = cb;
}
void signalAsync() {
// noodle noodle noodle
callback_->doSomethingWithSignalFromClassC();
}
}
即当我构造一个 C 对象时告诉它要回调的对象。
或者,您可以将其作为参数传递给 signalAsync,但也许那是不可能的
另一个想法是在构造函数中传递 std::function
,这样您就不必硬编码在 signalAsync
根据 pm100 的 answer,std::function
的用法确实有效。我想写下我最后做了什么,以防万一有人需要它。更详细一点,在我的例子中,C
的 header 文件不能包含 B
的 header 文件,因为 B
已经包含 C
在其 header 中(前向声明无效)。 C
也不能包含 A
,因为 A
被设计为一个实现 class(指向实现的指针);因此,A
header 位于 src
文件夹内,不应包含在任何地方(A.cc
除外)
我最后做了什么:
class A {
public:
std::unique_ptr<B> b;
void triggerAsynchronously() {
// this work is submitted to a queue.
b->getC()->signalAsync();
}
void setFunctionToC() {
// This happens before triggerAsynchronously()
auto do_something_when_finished = [&b = b]() {
b->doSomethingWithSignalFromClassC();
}
b->getC()->setFunctionToC(do_something_when_finished);
}
};
class C {
std::function<void()> call_on_finished;
public:
void setFunctionToC(std::function<void()> f) {
call_on_finished = f;
}
void signalAsync() {
// This function is submitted to a queue, and wait until its turn to be executed.
// I want to trigger A::b::doSomethingWithSignalFromC() once this function is done (aka end of this block)
call_on_finished();
}
}