根据我的理解,当一个流程进入一个关键部分时,没有其他流程可以同时进入。但是我通过一个程序看到它不是。
我创建了进程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
答案 0 :(得分:6)
要使信号量跨进程工作,它需要驻留在共享内存中并使用pshared==1
进行初始化 - 您不会将信号量放在共享内存中。查找例如shm_open
或mmap
。
您还应该在fork()
之前初始化信号量 - 初始化sempahore两次不起作用。也可以使用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();
}
}
答案 1 :(得分:2)
并检查sem_ *函数的返回值!从手册页:
sem_trywait()函数应该锁定 sem仅引用的信号量 如果信号量目前不是 锁定;也就是说,如果是信号量 价值目前是正面的。 否则,它不会锁定 信号量。
因此,如果您不检查它返回的内容,您根本不知道是否锁定了任何内容。
答案 2 :(得分:0)