在使用时,pthreads进程共享内存:docker run –ipc –pid

我正在C ++开发一个多处理的应用程序使用PTHREAD_PROCESS_SHARED pthread_rwlock pthreads实现IPC通过命名共享内存。 对于共享内存访问,我使用shm_openmmap

 auto fd = shm_open(name.c_str(), O_CREAT | O_RDWR, S_IRUSR | S_IWUSR); ftruncate(fd, size); addr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); 

rwlocksmmap -ed内存中被初始化,使用:

 pthread_rwlockattr_t attrrwlock; pthread_rwlockattr_init(&attrrwlock); pthread_rwlockattr_setpshared(&attrrwlock, PTHREAD_PROCESS_SHARED); pthread_rwlockattr_setkind_np(&attrrwlock, PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP); class Shm{ .... pthread_rwlock_t rwLock; ... } auto shm = Shm(addr); pthread_rwlock_init(&(shm.rwLock), &attrrwlock); 

这在主机环境中工作正常:我可以启动例如一个生产者和多个消费者/工作者进程使用相同的IPC共享内存文件,并通过进程共享pthread_rwlocks同步读/写共享内存:

 int errc = pthread_rwlock_timedrdlock(&rwLock, &abstime); errc = pthread_rwlock_timedwrlock(&rwLock, &abstime); errc = pthread_rwlock_unlock(&rwLock); 

因为我们在Docker容器中运行这个应用程序的实验,所以我需要启动第一个容器中的消费者/工作者进程以及其他容器中的顺序多个生产者进程。 为了使IPC工作,我只需在--ipc=container:<nome/id> docker run的调用中添加--ipc=container:<nome/id>即可。 现在所有的容器都使用了相同的共享内存。 一见钟情,locking似乎是正确的。 但偶尔一次, pthread_rwlock_timedrdlock返回EDEADLK错误代码,这是我以前没有遇到。 此外,经过一些更多的testing后,我得到了一些错误,看起来像并发的读/写错误。

首先我find了--cap-add docker run的参数--cap-add 。 Docker文档提到了mmap()shmctl()作为--cap-add用例的--cap-add

  IPC_LOCK Lock memory (mlock(2), mlockall(2), mmap(2), shmctl(2)). 

但是,将--cap-add=IPC_LOCK到我的--cap-add=IPC_LOCK docker run调用中并不能阻止pthread_rwlock_timedrdlock返回EDEADLK

然后,我读了docker中的PID-1-Problem,所以我想知道,pthread_rwlocks是否可能依赖于PID进行locking,当同一个PID试图lockingrwlock两次而不解锁时可能会感到困惑。 然后我find了--pid docker run--pid参数,其工作方式与--ipc相似。

现在,我使用:

 docker run -i -t -d --name=workers docker run -i -t --ipc=container:workers --pid=container:workers --name=producerN 

这似乎现在正常工作。

现在是否有人有关于docker IPC的更多细节,以及是否可以使用具有相同PID的进程共享pthread_rwlock

什么是IPC_LOCK pthread_rwlock需要吗?

主机:Docker版本17.03.0-ce Ubuntu 16.10 Linux 4.8.0-41

Docker容器:Ubuntu 16.04