开发者

What happens when a process enters a semaphore (critical section) and sleeps?

开发者 https://www.devze.com 2023-02-16 18:34 出处:网络
As per my understan开发者_运维问答ding, when a process enters a critical section, no other process can simultaneously enter. But i see, by a program, that it is not.

As per my understan开发者_运维问答ding, when a process enters a critical section, no other process can simultaneously enter. But i see, by a program, that it is not.

I create Process A, and child Process B. Child enters critical section, and sleeps, meanwhile i am surprised to see that parent too enters critical section, while child sleeps. How is it possible? 2 processes simultaneously at critical section?

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


For a semaphore to work across processes, it needs to reside in shared memory and to be initialized with pshared==1 - You're not putting the semaphore in shared memory. Look up e.g. shm_open or mmap.

You should also initialize the semaphore before you fork() - initializing a sempahore twice doesn't work. Also use sem_wait rather than sem_trywait as you seem to want to block on the semaphore. If you want sem_trywait at least check if the try part succeeded.

EDIT: Corrected source.

#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();
}
}


And check the return values of the sem_* functions! From the man page:

The sem_trywait() function shall lock the semaphore referenced by sem only if the semaphore is currently not locked; that is, if the semaphore value is currently positive. Otherwise, it shall not lock the semaphore.

So if you don't check what it returns, you don't know if you've locked anything at all.


You are using sem_trywait function,then you should check the value returned by this call so as to ensure sysnchronization...

Can refer this for more help....

Hope this helps...

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号