簡體   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