我想要一个简单的跨流程障碍解决方案。这是一个解决方案:solution
但我完全迷失了mmap ...在第一次尝试时,它失败了十次(段错误或死锁)。
我理解我的问题来自同步问题,但我找不到它。我找到了一个设置mmaped内存(example)的示例,但我不确定它对mmaped pthread_barrier有好处。
这是我的代码摘录:
#define MMAP_FILE "/tmp/mmapped_bigdft.bin"
void init_barrier() {
pthread_barrier_t *shared_mem_barrier;
pthread_barrierattr_t barattr;
pthread_barrierattr_setpshared(&barattr, PTHREAD_PROCESS_SHARED);
hbcast_fd = open(MMAP_FILE, O_RDWR | O_CREAT | O_TRUNC, (mode_t)0600);
result = lseek(hbcast_fd, sizeof(pthread_barrier_t)-1, SEEK_SET);
result = write(hbcast_fd, "", 1);
shared_mem_barrier = (pthread_barrier_t*) mmap(0, sizeof(pthread_barrier_t), PROT_READ | PROT_WRITE, MAP_SHARED, hbcast_fd, 0);
if (mpi_rank == 0) {
int err = pthread_barrier_init(shared_mem_barrier, &barattr, host_size);
}
MPI_Barrier(some_communicator);
}
问题:
新问题
管理pthread屏障哪个更安全?或者他们是基于相同的机制?
答案 0 :(得分:2)
正如查尔斯所提到的那样,看起来截断就是让你感觉到的。此外,您应该使用pthread_barrierattr_init初始化属性。
至于另一个问题,只需要一个进程进行初始化,然后所有进程都应该调用pthread_barrier_wait(就像使用MPI一样)。
我看到了你的另一个问题,所以我知道为什么你不想使用MPI。因此,您可能只需要一个MPI屏障来初始化您的pthread障碍,如下所示:
if (rank == 0)
{
/* Create the shared memory segment, initialise the barrier. */
}
MPI_Barrier(communicator);
if (rank != 0)
{
/* Load the shared memory segment, cast it to a pthread_barrier_t* and store.
* It's already initialised */
}
答案 1 :(得分:1)
您不希望为每个进程使用O_TRUNC打开该文件。每次执行此操作时,您将再次截断文件,并可能使您执行的先前mmap操作无效(更改文件大小时对前一个mmap的影响通常是未定义的)。
除此之外,我认为你不能在mmap的内存中拥有信号量并使其正常运行(它可能在某些操作系统平台上,所以我怀疑它通常可以保证以你想要的方式运行)。 / p>
您真正想要使用的是共享内存。做“shmget”和“shmat”的人要学习如何创建和映射共享内存。您可能仍然需要一个文件来传递共享内存ID,并且应该注意通过注册信号处理程序在应用程序崩溃期间释放共享内存ID。否则,您可以保留僵尸共享内存分配并超出您的操作系统资源限制。如果在尝试在主线程上创建共享内存段时获得ENOSPC,您就会知道发生了这种情况。
答案 2 :(得分:1)
您应该使用shm_open
来创建共享细分。
O_CREAT
你
应该能够检测一个过程
是第一个创建细分的人。