0

据我了解,当一个进程进入临界区时,没有其他进程可以同时进入。但我看到,通过一个程序,它不是。

我创建了进程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
4

3 回答 3

6

对于跨进程工作的信号量,它需要驻留在共享内存中并进行初始化pshared==1- 您没有将信号量放在共享内存中。查找例如shm_openmmap

您还应该在您之前初始化信号量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();
}
}
于 2011-03-13T17:18:24.283 回答
2

并检查 sem_* 函数的返回值!从手册页:

sem_trywait() 函数仅在信号量当前未锁定时才锁定 sem 引用的信号量;也就是说,如果信号量值当前为正。否则,它不应锁定信号量。

所以如果你不检查它返回的内容,你根本不知道你是否锁定了任何东西。

于 2011-03-13T17:19:26.623 回答
0

您正在使用 sem_trywait 函数,那么您应该检查此调用返回的值,以确保 sysnchronization...

可以参考 这个 以获得更多帮助....

希望这可以帮助...

于 2011-03-13T17:25:12.340 回答