Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.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++ 跨std实现工作的互斥体_C++_Mutex - Fatal编程技术网

C++ 跨std实现工作的互斥体

C++ 跨std实现工作的互斥体,c++,mutex,C++,Mutex,与之相关的是,我需要一个跨std实现的互斥锁,或者一种原子化地写入和读取指针的方法。一个线程是由使用mingw-w64编译的代码生成的,另一个线程是静态/动态库中的Visual Studio 2019代码。从主可执行文件(mingw-w64)导出到DLL(VC++)-使用单独的编译器编译-同步/互斥“句柄”(通常是不透明指针,但也可以是指向某个对象的索引)还有一对C风格的函数(如果您愿意,可以将它们封装到类中,如std::mutex和std::lock,公开相同的API-这是最安全的做法)锁定和

与之相关的是,我需要一个跨
std
实现的互斥锁,或者一种原子化地写入和读取指针的方法。一个线程是由使用mingw-w64编译的代码生成的,另一个线程是静态/动态库中的Visual Studio 2019代码。

从主可执行文件(mingw-w64)导出到DLL(VC++)-使用单独的编译器编译-同步/互斥“句柄”(通常是不透明指针,但也可以是指向某个对象的索引)还有一对C风格的函数(如果您愿意,可以将它们封装到类中,如
std::mutex
std::lock
,公开相同的API-这是最安全的做法)锁定和解锁该句柄。它们可以如此简单,也可以包含额外的功能,比如超时,或者尝试锁定——这些功能非常有用,但不是必需的。您还可以导出
handle\u t create()
void delete(handle\u t handle)
函数


关键是同步对象本身(互斥体或其他)总是由这些间接函数操纵,以避免使用中出现错误,并且这些函数根据编译器(预处理器很容易检测到)由编译器特定的原子操作内部函数或CRT函数支持,类似于完美的(它也在明文W64下工作)和它的VisualC++特定的,或者GCC的(更具体地说,AythAythixCopaReExchange < /COD>)。< /P> < P>从主可执行文件(明文W64)导出到DLL(VC++)-用单独的编译器编译-同步/互斥“句柄”(通常是一个不透明的指针,尽管它也可以是某个对象的索引)和一对C风格的函数(如果您愿意,可以将它们封装到类中,如
std::mutex
std::lock
,公开相同的API-这是最安全的做法)使用该句柄的锁定和解锁功能。它们可以是如此简单,也可以包括诸如超时之类的附加功能,或者尝试锁定-这些功能非常有用,但不是必需的。您还可以导出
handle\t create()
void delete(handle\t handle)
函数

关键是同步对象本身(互斥体或其他)总是由那些间接函数来操作,以避免使用中出现错误,并且这些函数根据编译器的不同而不同(预处理器很容易检测到)支持编译器特定的原子操作本质或CRT函数,如完全拟合(它也在明文W64下工作)和它的Visual C++特定的,或者GCC的(更具体地说,<代码> 虚空锁()=0; 虚空解锁()=0; 虚拟~imutex(){} }; 模板 结构imp_互斥体:imutex{ M M; void lock()最终重写{m.lock();} void unlock()最终覆盖{m.unlock();} }; 结构mymutex{ 使用up=std::unique\u ptr; mymutex(向上m_-in):m(std::move(m_-in)){ mymutex():mymutex(up(newimp_mutex{},[](imutex*m){delete m;})){} void lock(){m->lock();} void unlock(){m->unlock();} mymutex(mymutex&&)=删除; 私人: 上m; }; 这假设vtables和std::unique_ptr的ABI兼容性是合理的

如果不是,用自定义的东西替换unique ptr,并用取空指针的函数指针替换虚拟方法

关键是,互斥锁是在一个库的代码中创建和销毁的

这是一个纯函数指针,它依赖于包含两个三个PTR的结构具有相同的布局,并且thr C调用约定是相同的

无论哪个库生成mymutex,都可以使用它

struct imutex_vtable {
  void (*lock)(void*) = 0;
  void (*unlock)(void*) = 0;
  void (*dtor)(void*)=0;
};
template<class M>
imutex_vtable const* get_imutex_vtable(){
  static const imutex_vtable vtable = {
    [](void* m){ static_cast<M*>(m)->lock(); },
    [](void* m){ static_cast<M*>(m)->unlock(); },
    [](void* m){ delete static_cast<M*>(m); }
  };
  return &vtable;
}

struct mymutex {
  mymutex( imutex_vtable const* vt, void* pm ):vtable(vt), pv(pm){}
  template<class M>
  explicit mymutex(std::unique_ptr<M> m):mymutex( get_imutex_vtable<M>(), m.release() ) {}
  mymutex():mymutex(std::make_unique<std::mutex>()) {}
  void lock(){ vtable->lock(pv); }
  void unlock(){ vtable->unlock(pv); }
  ~mymutex(){ vtable->dtor(pv); }
  mymutex(mymutex&&)=delete;
private:
  imutex_vtable const* vtable=0;
  void* pv=0;
};
struct imutex\u vtable{
无效(*锁定)(无效*)=0;
无效(*解锁)(无效*)=0;
无效(*dtor)(无效*)=0;
};
模板
imutex_vtable常量*获取imutex_vtable(){
静态常数imutex\u vtable vtable={
[](void*m){static_cast(m)->lock();},
[](void*m){static_cast(m)->unlock();},
[](void*m){delete static_cast(m);}
};
返回&vtable;
}
结构mymutex{
mymutex(imutex_vtable const*vt,void*pm):vtable(vt),pv(pm){}
模板
显式mymutex(std::unique_ptr m):mymutex(get_imutex_vtable(),m.release()){}
mymutex():mymutex(std::make_unique()){}
void lock(){vtable->lock(pv);}
void unlock(){vtable->unlock(pv);}
~mymutex(){vtable->dtor(pv);}
mymutex(mymutex&&)=删除;
私人:
imutex_vtable const*vtable=0;
void*pv=0;
};

这基本上是使用C类实现实现C++接口继承的一个简单案例,然后将其封装在类和模板中,这样用户就不会注意到。 虚空锁()=0; 虚空解锁()=0; 虚拟~imutex(){} }; 模板 结构imp_互斥体:imutex{ M M; void lock()最终重写{m.lock();} void unlock()最终覆盖{m.unlock();} }; 结构mymutex{ 使用up=std::unique\u ptr; mymutex(向上m_-in):m(std::move(m_-in)){ mymutex():mymutex(up(newimp_mutex{},[](imutex*m){delete m;})){} void lock(){m->lock();} void unlock(){m->unlock();} mymutex(mymutex&&)=删除; 私人: 上m; }; 这假设vtables和std::unique_ptr的ABI兼容性是合理的

如果不是,用自定义的东西替换unique ptr,并用取空指针的函数指针替换虚拟方法

关键是,互斥锁是在一个库的代码中创建和销毁的

这是一个纯函数指针,它依赖于包含两个三个PTR的结构具有相同的布局,并且thr C调用约定是相同的

无论哪个库生成mymutex,都可以使用它

struct imutex_vtable {
  void (*lock)(void*) = 0;
  void (*unlock)(void*) = 0;
  void (*dtor)(void*)=0;
};
template<class M>
imutex_vtable const* get_imutex_vtable(){
  static const imutex_vtable vtable = {
    [](void* m){ static_cast<M*>(m)->lock(); },
    [](void* m){ static_cast<M*>(m)->unlock(); },
    [](void* m){ delete static_cast<M*>(m); }
  };
  return &vtable;
}

struct mymutex {
  mymutex( imutex_vtable const* vt, void* pm ):vtable(vt), pv(pm){}
  template<class M>
  explicit mymutex(std::unique_ptr<M> m):mymutex( get_imutex_vtable<M>(), m.release() ) {}
  mymutex():mymutex(std::make_unique<std::mutex>()) {}
  void lock(){ vtable->lock(pv); }
  void unlock(){ vtable->unlock(pv); }
  ~mymutex(){ vtable->dtor(pv); }
  mymutex(mymutex&&)=delete;
private:
  imutex_vtable const* vtable=0;
  void* pv=0;
};
struct imutex\u vtable{
无效(*锁定)(无效*)=0;
无效(*解锁)(无效*)=0;
无效(*dtor)(无效*)=0;
};
模板
imutex_vtable常量*获取imutex_vtable(){
静态常数imutex\u vtable vtable={
[](void*m){static_cast(m