2016-11-11 6 views
0

Я пишу программу для проверки межпроцессного общения, в частности, общей памяти POSIX. Я использую семафоры POSIX для синхронизации доступа процессов к общей памяти. (Я читал, что функция posix sem_open позволяет использовать один и тот же семафор между процессами, если вы используете один и тот же идентификатор «name».)сфабрирование с помощью одного процесса

Проблема - когда я выполняю sem_wait и sem_post один процесс ... другой процесс не захватывает семафор. Процесс 1 просто запускает семафор и выпускает его, а затем берет его обратно, не давая другому процессу возможности вмешаться.

Вот код на процесс 1

if ((sem1 = sem_open(request->mem_group.sem_name, O_CREAT, 0644, 0)) == 
     SEM_FAILED) { 
     perror("sem_open"); 
     goto finish; 
     } 

cache = simplecache_get(request->file_path); 
    *(int *)mem_shared = cache == -1 ? -1 : 1; 
    sem_post(sem); 
    sem_wait(sem); 
    if (cache == -1) { 
     break; 


     fprintf(stdout, "File was not found, going to finish\n"); 
    } 


    file_length = lseek(cache, 0, SEEK_END); 
    lseek(cache, 0, SEEK_SET); 
    *(size_t *)mem_shared = file_length; 

    sem_post(sem); 
    sem_wait(sem1); 

    if (!file_len) { 
     goto finish; 
    } 

    bytes_transferred = 0; 
    while (bytes_transferred < file_len) { 

       //rest of while loop here which transfers file 

А вот блок кода в процессе 2, где он должен ловить семафор, но не

sem_wait(sem1); 

file_size = *(size_t *)mem_shared; 

gfs_sendheader(ctx, GF_OK, file_size); 

sem_post(sem1); 

if (!file_size) { 
    fprintf(stderr, "File is empty. Go to finish"); 
    break; 
} 

Так что идея является - этот процесс 2 должен получать экземпляр между post/wait в другом процессе - и в этот момент сегмент разделяемого сегмента имеет в нем данные и не пуст. Однако вместо этого он ловит семафор в самом конце другого процесса, когда он освободил сегмент сахредной памяти и удалил любые данные внутри него.

Я сделал много стрельбы неприятности и подтвердил, что а) семафор тот же семафор в каждом процессе б) Процесс 1 имеет в некоторой точке приращение семафора, а затем поймать тот же семафор и уменьшить его (проверено это с sem_getvalue)

Я запускаю это на виртуальной машине Ubuntu через виртуальную машину Oracle VM VirtualBox. Основной ноутбук - это Microsoft Surfacebook.

Затруднялись с этой проблемой в течение 48 часов и чувствовали себя крайне обескураженными. Любые советы или рекомендации о том, как более стратегически отлаживать его, также будут оценены.

ответ

0

Это не имеет смысла:

sem_post(sem); 
sem_wait(sem1); 

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

Обычно один процесс будет отправлен, а другой будет ждать. Затем выполняется первый процесс, и он может публиковать снова, если у него больше работы для второго процесса, который ждет по мере необходимости. Если двум процессам необходимо координировать свои действия (т. Е. Первый процесс приостанавливается до тех пор, пока второй не скажет, что это нормально), вы должны использовать второй семафор, и на этом первый процесс всегда будет ждать, а второй -. Таким образом, один конкретный процесс только когда-либо ждет или публикует сообщения на определенном семафоре, ни один из них.

+0

Большое спасибо, gilez. Вы правы, я думал, что могу использовать его как мьютекс, и если другой процесс был в sem_wait, он должен был быть первым в очереди. Благодарим вас за очень полезный ответ – rafiya

+0

@raf, вы не можете делать никаких предположений о том, какой процесс (или поток) будет отправлен при публикации. Глядя кратко, я не могу найти ссылку, но если вы код без таких предположений, вы будете в безопасности :-) – gilez

Смежные вопросы