Интер обрабатывает разделяемую память и pthread_barrier: как быть в безопасности? - PullRequest
2 голосов
/ 20 декабря 2010

Я хотел простое решение для межпроцессного барьера. Вот решение: решение

Но я полностью потерян с mmap ... С моей первой попытки, она терпит неудачу один из десяти раз (segfault или deadlock).

Я понимаю, что моя проблема связана с проблемой синхронизации, но я не могу ее найти. Я нашел пример для настройки памяти mmaped ( пример ), но я не уверен, что это хорошо для 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);
}

Вопросы:

  • я что-то пропускаю при инициализации mmap?
  • какая операция должна выполняться всеми процессами, а какая только одним?

Новый вопрос

Что безопаснее для управления барьером pthread? Или они основаны на одном и том же механизме?

  • shmget
  • shm_open
  • ММАП
  • еще один

Ответы [ 3 ]

2 голосов
/ 20 декабря 2010

Как сказал Чарльз, похоже, что именно усечение - то, что вас заводит. Кроме того, вы должны инициализировать атрибуты, используя 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 голос
/ 20 декабря 2010

Вы должны использовать shm_open для создания общего сегмента.

  • с параметром O_CREAT вы должен быть в состоянии обнаружить, если процесс первым создает сегмент.
  • Только этот процесс должен обрезаться отрезок до соответствующей длины, отобразите его и инициализировать барьер.
  • Все остальные, которые обнаруживают, что они не первые должны спать на в то время как секунды должно быть достаточно, а затем отобразить сегмент.
  • После этого все процессы могут синхронизировать шлагбаум.
1 голос
/ 20 декабря 2010

Вы не хотите открывать файл с помощью O_TRUNC для каждого процесса.Каждый раз, когда вы делаете это, вы снова усекаете файл и потенциально лишаете законной силы предыдущие выполненные вами операции mmap (влияние на предыдущие mmap при изменении размера файла обычно не определено).

Если оставить в сторонеНе думайте, что вы можете иметь семафор в памяти mmap'd и правильно его функционировать (это может быть на некоторых платформах ОС, поэтому я сомневаюсь, что он, как правило, гарантированно функционирует так, как вы хотите).действительно хочу использовать разделяемую память.Сделайте man на «shmget» и «shmat», чтобы научиться создавать и отображать общую память.Вам, вероятно, все еще понадобится файл для передачи идентификатора общей памяти, и вы должны быть осторожны при освобождении идентификатора совместно используемой памяти во время сбоев приложения путем регистрации обработчиков сигналов.В противном случае вы можете оставить распределение общей памяти зомби без присмотра и превысить ограничения ресурсов вашей ОС.Вы узнаете, что произошло, если получите ENOSPC при попытке создать сегмент общей памяти в вашем основном потоке.

...