boost::OSX 上 32 位和 64 位程序之间共享内存中的进程间同步机制(互斥体、条件)



OSX 10.11.6,提升1.63.0

我有一个64位master进程,它使用一个32位slave过程来进行一些实时渲染(我没有特定32位动态库的源代码,因此无法将其重新编译为64位)。时机很关键,我发现boost::interprocess的共享内存实用程序运行得很好,但我遇到了互操作性问题。当编译32与64&因此,当从共享内存引用它们时,会导致问题。

64 bit
Scoped Lock: 16
Condition: 48
Mutex: 64
Semaphore: 4
32 bit
Scoped Lock: 8
Condition: 28
Mutex: 44
Semaphore: 4

我深入研究了boost::interprocess::interprocess_mutex标头,发现了_pthread_types.h:中声明的大小

// pthread opaque structures
#if defined(__LP64__)
#define __PTHREAD_SIZE__        8176
#define __PTHREAD_ATTR_SIZE__       56
#define __PTHREAD_MUTEXATTR_SIZE__  8
#define __PTHREAD_MUTEX_SIZE__      56
#define __PTHREAD_CONDATTR_SIZE__   8
#define __PTHREAD_COND_SIZE__       40
#define __PTHREAD_ONCE_SIZE__       8
#define __PTHREAD_RWLOCK_SIZE__     192
#define __PTHREAD_RWLOCKATTR_SIZE__ 16
#else // !__LP64__
#define __PTHREAD_SIZE__        4088
#define __PTHREAD_ATTR_SIZE__       36
#define __PTHREAD_MUTEXATTR_SIZE__  8
#define __PTHREAD_MUTEX_SIZE__      40
#define __PTHREAD_CONDATTR_SIZE__   4
#define __PTHREAD_COND_SIZE__       24
#define __PTHREAD_ONCE_SIZE__       4
#define __PTHREAD_RWLOCK_SIZE__     124
#define __PTHREAD_RWLOCKATTR_SIZE__ 12
#endif // !__LP64__
struct _opaque_pthread_mutex_t {
long __sig;
char __opaque[__PTHREAD_MUTEX_SIZE__];
};

使用时

boost::interprocess::interprocess_mutex
boost::interprocess::interprocess_condition

两个程序都编译为64位,数据呈现效果非常好。

有什么方法可以强制尺寸一致吗?或者我忽略了另一种IPC机制?

使用条件的好处是,它们可以向被阻塞的线程发出何时唤醒的信号,并大大减少浪费的CPU周期,因为等待的线程/进程不必不断运行来检查值。有没有其他方法可以用这种方式向线程/进程发出信号?

据我所知,OSX上至少有几个程序实现了64位<->之间的快速高效数据渲染32位,所以答案一定在某个地方。。

所以我接受了MikeMB&对管道做了一些研究。我找到了这张纸http://ace.ucv.ro/sintes12/SINTES12_2005/SOFTWARE%20ENGINEERING/44.pdf其建议使用管道作为锁定机构。对管道的读/写似乎实现了与进程间条件变量相同的信号机制,因此线程阻塞/唤醒非常有效。

看起来读/写速度足够快,可以在我的机器上进行实时设置!(尽管def还不能保证它能在其他机器上运行,但我只在2011年的MBP(2.2 GHz英特尔酷睿i7)上进行了测试)

它似乎和条件一样有效,我还没有得到任何数据丢失。这是我做的。只需将其中一个放在共享内存中,masterslave进程就可以调用wait()&post()。

struct PipeSemaphore
{
PipeSemaphore()
{
// make sure semaphore will work in shared memory
// between 32 <-> 64 bit processes
static_assert (sizeof (int) == 4);
int res = pipe (p);
// pipe failed to open
if (res == -1)
assert (false);
}
~PipeSemaphore()
{
close (p[0]);
close (p[1]);
}
// if nothing is in the pipe stream,
// the curr thread will block
inline int wait() noexcept
{
char b;
return read (p[0], &b, 1);
}
// writing to the pipe stream will notify
// & wake blocked threads
inline int post() noexcept
{
return write (p[1], "1", 1);
}
private:
int p[2];
};

任何对代码的建议都将不胜感激!

最新更新