c - 当进程进入信号量(临界区)并休眠时会发生什么?

标签 c linux semaphore critical-section

按照我的理解,当一个进程进入临界区时,其他进程不能同时进入。但我通过程序看到它不是。

我创建进程 A 和子进程 B。 child 进入临界区,然后 sleep ,同时我很惊讶地看到 parent 也进入临界区,而 child sleep 。这怎么可能? 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() 之前初始化信号量 - 两次初始化信号量是行不通的。还可以使用 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();
}
}

关于c - 当进程进入信号量(临界区)并休眠时会发生什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5290985/

相关文章:

C SOCKS5 代理接口(interface)未从代理服务器接收任何内容。

linux - bash 中数字数组中的数学运算..?

linux - 需要帮助 shell 脚本来过滤所有者机器列表

java - sleep 的理发师,信号量?

c - 如何理解多线程和互斥原语

c - 为什么这个运算等于1?

c++ - 为什么包括与RTCZero库不兼容?

php - 为 Web 开发人员预装 Linux?

c - 我怎样才能知道类 unix 操作系统是否实现了 POSIX 信号量?

c - C 中的二维字符串