假设,我有一个可能从另一个线程中取消的任务.该任务在C函数中执行,另一个线程运行C++代码.我怎么做?
粗略的例子.
C:
void do_task(atomic_bool const *cancelled);
Run Code Online (Sandbox Code Playgroud)
C++:
std::atomic_bool cancelled;
…
do_task(&cancelled);
Run Code Online (Sandbox Code Playgroud)
现在,我创建了一个atomics.h包含以下内容的文件:
#ifdef __cplusplus
#include <atomic>
using std::atomic_bool;
#else
#include <stdatomic.h>
#endif
Run Code Online (Sandbox Code Playgroud)
它似乎有效,但我没有看到任何保证.我想知道,如果有更好的(正确的)方式.
为了解决所有ABI问题,您可能希望实现从C++调用的C函数并对其进行操作atomic_bool.这样,您的C++代码不需要知道有关该全局变量及其类型的任何信息:
在一个.h文件中:
#ifdef __cplusplus
extern "C" {
#endif
void cancel_my_thread(void);
int is_my_thread_cancelled(void);
#ifdef __cplusplus
}
#endif
Run Code Online (Sandbox Code Playgroud)
然后在一个.c文件中:
#include <stdatomic.h>
static atomic_bool cancelled = 0;
void cancel_my_thread(void) {
atomic_store_explicit(&cancelled, 1, memory_order_relaxed);
}
int is_my_thread_cancelled(void) {
return atomic_load_explicit(&cancelled, memory_order_relaxed);
}
Run Code Online (Sandbox Code Playgroud)
C++代码将包括前进和调用cancel_my_thread.
在atomic_bool用C型和std::atomic<bool>在C++型(如通过typedef std::atomic_bool)是两种不同类型的不相关.传递std::atomic_bool给期望C的C函数atomic_bool是未定义的行为.它的工作原理是运气和这些类型的简单定义兼容.
如果C++代码需要调用一个期望C的C函数atomic_bool,那么它就是必须使用的.但是,C++ 中不存在<stdatomic.h>标头.您必须为C++代码提供一种方法来调用C代码,以隐藏类型的方式获取指向所需原子变量的指针.(可能声明一个包含原子bool的结构,C++只会知道该类型存在并且只知道指向它的指针.)