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

时间:2017-01-21 03:42:06

标签: c++ macos ipc shared-memory boost-interprocess

OSX 10.11.6,提升1.63.0

我有一个64位进程正在使用32位从属进程来进行实时渲染(我没有源代码到特别是32位动态库,所以我不能将其重新编译为64位)。时机至关重要,我发现boost :: interprocess的共享内存实用程序运行良好,但我遇到了互操作性问题。在编译32对64和64时,一些进程间机制是不同的大小。因此,当 slave 从共享内存中引用它们时会导致问题。

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位,所以答案必须在某个地方......

1 个答案:

答案 0 :(得分:1)

所以我接受了MikeMB& amp;对管道做了一些研究。我发现这篇论文http://ace.ucv.ro/sintes12/SINTES12_2005/SOFTWARE%20ENGINEERING/44.pdf建议使用管道作为锁定机制。看起来像读取/写入管道实现了进程间条件变量的相同信号机制,因此线程阻塞/唤醒非常有效。

看起来读/写速度足以让我在我的机器上实时设置! (def不能保证它可以在其他机器上运行,但我只在我的2011 MBP(2.2 GHz Intel Core i7)上测试过)

它似乎和条件一样有效,但我还没有获得任何数据丢失。这就是我的所作所为。只需将其中一个放在共享内存中,从属进程就可以调用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];
};

非常感谢对代码的任何建议!