[英]What happens when a process enters a semaphore (critical section) and sleeps?
As per my understanding, 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. 我创建了流程A,孩子创建了流程B。孩子进入关键部分并入睡,与此同时,我很惊讶地看到父母也进入了关键部分,而孩子却入睡。 How is it possible?
这怎么可能? 2 processes simultaneously at critical section?
关键部分同时进行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
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. 为了使信号量跨进程工作,它必须驻留在共享内存中,并使用
pshared==1
进行初始化-您无需将信号量放入共享内存中。 Look up eg shm_open
or mmap
. 查找例如
shm_open
或mmap
。
You should also initialize the semaphore before you fork()
- initializing a sempahore twice doesn't work. 您还应该在
fork()
之前初始化信号量-两次初始化sempahore无效。 Also use sem_wait
rather than sem_trywait
as you seem to want to block on the semaphore. 也可以使用
sem_wait
而不是sem_trywait
因为您似乎想阻止信号量。 If you want sem_trywait
at least check if the try
part succeeded. 如果要
sem_trywait
至少检查try
部分是否成功。
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! 并检查sem_ *函数的返回值! From the man page:
从手册页:
The sem_trywait() function shall lock the semaphore referenced by sem only if the semaphore is currently not locked;
sem_trywait()函数仅在当前未锁定信号量的情况下,才应锁定sem引用的信号量。 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. 因此,如果不检查返回的内容,就根本不知道是否锁定了任何内容。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.