2+线程在等待interprocess_condition变量时遇到了一个非常奇怪的问题。
升压1.60.0
Test.cpp:
#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/sync/interprocess_mutex.hpp>
#include <boost/interprocess/sync/interprocess_condition.hpp>
#include <iostream>
using namespace boost::interprocess;
struct Data {
interprocess_mutex mux_;
interprocess_condition cond_;
};
int main(int argc, char *argv[]) {
if (argc > 1 && atoi(argv[1]) == 0) {
struct shm_remove {
shm_remove() { shared_memory_object::remove("MySharedMemory"); }
~shm_remove() { shared_memory_object::remove("MySharedMemory"); }
} remover;
managed_shared_memory seg(create_only, "MySharedMemory", 65536);
Data *const d = seg.construct<Data>(unique_instance)();
scoped_lock<interprocess_mutex> lock(d->mux_);
std::cout << "Waiting" << std::endl;
d->cond_.wait(lock);
} else if (argc > 1 && atoi(argv[1]) == 1) {
managed_shared_memory seg(open_only, "MySharedMemory");
std::pair<Data *, std::size_t> res = seg.find<Data>(unique_instance);
scoped_lock<interprocess_mutex> lock(res.first->mux_);
std::cout << "Waiting" << std::endl;
res.first->cond_.wait(lock);
} else {
managed_shared_memory seg(open_only, "MySharedMemory");
std::pair<Data *, std::size_t> res = seg.find<Data>(unique_instance);
scoped_lock<interprocess_mutex> lock(res.first->mux_);
std::cout << "Notifying" << std::endl;
res.first->cond_.notify_all();
}
}汇编如下:
$ clang++ -I/usr/local/include test.cpp使用1 wait()和1 notify()运行:
$ ./a.out 0&
[8] 25889
Waiting
$ ./a.out 2&
[9] 25901
Notifying
[8]- Done ./a.out 0
[9]+ Done ./a.out 2在两个等待中运行:
$ ./a.out 0&
[8] 25986
Waiting
$ ./a.out 1&
[9] 25998
Waiting
Assertion failed: (res == 0), function do_wait, file /usr/local/include/boost/interprocess/sync/posix/condition.hpp, line 175.在OSX El Capitan上测试
$ uname -a
Darwin LUS-JOHUGHES2 15.3.0 Darwin Kernel Version 15.3.0: Thu Dec 10 18:40:58 PST 2015; root:xnu-3248.30.4~1/RELEASE_X86_64 x86_64我还在一个Ubuntu可靠的机器上尝试了上面的例子,所有的例子都像预期的那样工作,这让我相信OSX的实现有问题。我还没有在Windows上试过。
发布于 2016-02-13 18:45:49
做了些调查,找到了这个问题的确切答案。
因此,开展这项工作的两个备选方案如下:
我并没有深入到glibc线程代码中去了解它们与Apple的不同之处,所以我不知道为什么最初的示例在Linux上工作,而不是OSX。
我认为Boost docs肯定会受益于一段讨论这个陷阱的段落。
发布于 2018-04-22 22:29:41
这是达尔文C库和Boost.Interprocess上的一个bug。首先,C库声称它符合posix,并且支持进程共享内存条件变量,这是假的(因为它使用原始指针来存储互斥对象的地址)。第二,Boost.Interprocess应该将这个平台检测为一个buggy,应该禁用线程的使用并回退到仿真。
在boost/interprocess/detail/workound.hpp中,您会看到一条评论:
//Mac Os X < Lion (10.7) might define _POSIX_THREAD_PROCESS_SHARED but there is no real support.
一些旧的报告声称较新的macos版本确实支持进程共享条件变量,但是这个声明是错误的,所以__APPLE__部分应该是正确的:
#define BOOST_INTERPROCESS_BUGGY_POSIX_PROCESS_SHARED
https://stackoverflow.com/questions/35305291
复制相似问题