繁体   English   中英

当进程进入信号灯(关键部分)并进入休眠状态时会发生什么?

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

根据我的理解,当一个进程进入关键部分时,没有其他进程可以同时进入。 但是我看到,通过一个程序,事实并非如此。

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

为了使信号量跨进程工作,它必须驻留在共享内存中,并使用pshared==1进行初始化-您无需将信号量放入共享内存中。 查找例如shm_openmmap

您还应该在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();
}
}

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

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

因此,如果不检查返回的内容,就根本不知道是否锁定了任何内容。

您正在使用sem_trywait函数,然后应检查此调用返回的值,以确保系统同步...

可以参考以获得更多帮助。

希望这可以帮助...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM