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

发布于 2024-10-21 17:47:16 字数 858 浏览 0 评论 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

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. How is it possible? 2 processes simultaneously at critical section?

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

时常饿 2024-10-28 17:47:16

对于跨进程工作的信号量,它需要驻留在共享内存中并使用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();
}
}

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. Look up e.g. shm_open or mmap.

You should also initialize the semaphore before you fork() - initializing a sempahore twice doesn't work. Also use sem_wait rather than sem_trywait as you seem to want to block on the semaphore. If you want sem_trywait at least check if the try part succeeded.

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();
}
}
始于初秋 2024-10-28 17:47:16

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

sem_trywait() 函数应锁定
仅由 sem 引用的信号量
如果信号量当前不是
锁定;也就是说,如果信号量
目前价值为正。
否则不予锁定
信号量。

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

And check the return values of the sem_* functions! From the man page:

The sem_trywait() function shall lock
the semaphore referenced by sem only
if the semaphore is currently not
locked; 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.

維他命╮ 2024-10-28 17:47:16

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

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

希望这有帮助...

You are using sem_trywait function,then you should check the value returned by this call so as to ensure sysnchronization...

Can refer this for more help....

Hope this helps...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文