What happens when a process enters a semaphore (critical section) and sleeps?
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...
精彩评论