Что происходит, когда процесс входит в семафор (критическая секция) и спит? - PullRequest
0 голосов
/ 13 марта 2011

Насколько я понимаю, когда процесс входит в критическую секцию, ни один другой процесс не может одновременно войти. Но я вижу по программе, что это не так.

Я создаю Процесс A, а дочерний Процесс B. Ребенок входит в критическую секцию и спит, в то же время я удивлен, что родитель тоже входит в критическую секцию, пока ребенок спит. Как это возможно? 2 процесса одновременно на критическом участке?

enter code here
#include <semaphore.h>
#include <unistd.h>
#include <stdio.h>

sem_t sem;
int shared=0;
int pid;

void func()
{
 sem_trywait(&sem);
 if(pid==0)printf("Child entered\n");
 else if(pid>0)printf("Parent entered\n");
 sleep(2);
 shared++;
 sem_post(&sem);
 if(pid==0)printf("Child exited\n");
 else if(pid>0)printf("Parent exited\n");
}

int main()
{
 pid=fork();
 sem_init(&sem,1,0);
 if(pid==0){
  printf("In child\n");
  func();
 }
 else {
 func();
}
}
Output:
 [root@dhcppc0 semaphore]# gcc semaphore1.c -lrt
 [root@dhcppc0 semaphore]# ./a.out
  In child
  Child entered
  Parent entered

  <pause 2 secs>

  Child exited
  Parent exited

Ответы [ 3 ]

6 голосов
/ 13 марта 2011

Чтобы семафор работал в разных процессах, он должен находиться в общей памяти и инициализироваться с помощью pshared==1 - Вы не помещаете семафор в общую память.Посмотрите, например, shm_open или mmap.

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

РЕДАКТИРОВАТЬ: исправленный источник.

#include <semaphore.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/mman.h>

sem_t * sem; /* MODIFIED: We want a semaphore in shared memory, using a pointer instead */
int shared=0;
int pid;

void func()
{
 sem_wait(sem); /* MODIFIED &sem to sem */
 if(pid==0)printf("Child entered\n");
 else if(pid>0)printf("Parent entered\n");
 sleep(2);
 shared++;
 sem_post(sem); /* MODIFIED &sem to sem */
 if(pid==0)printf("Child exited\n");
 else if(pid>0)printf("Parent exited\n");
}

int main()
{
  /* MODIFIED: Put semaphore in shared memory */
  sem = mmap(0, sizeof(sem_t), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
 /* MODIFIED: Initial count of 1, so that a sem_wait will succeed */
 sem_init(sem,1,1);
 /* MODIFIED: fork() after sem_init() */
 pid=fork();
 if(pid==0){
  printf("In child\n");
  func();
 }
 else {
 func();
}
}
2 голосов
/ 13 марта 2011

И проверьте возвращаемые значения функций sem_ *! Со страницы руководства:

Функция sem_trywait () должна заблокироваться семафор, на который ссылается только sem если семафор в настоящее время не заблокирован; то есть если семафор значение в настоящее время положительное. В противном случае он не должен блокировать семафор.

Так что, если вы не проверяете, что он возвращает, вы не знаете, заблокировали ли вы что-либо вообще.

0 голосов
/ 13 марта 2011

Вы используете функцию sem_trywait, затем вам следует проверить значение, возвращаемое этим вызовом, чтобы обеспечить sysnchronization ...

Может ссылаться на this для получения дополнительной помощи ....

Надеюсь, это поможет ...

...