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_openまたは などを検索しmmapます。

また、その前にセマフォを初期化する必要があります。セマフォをfork()2 回初期化しても機能しません。また、セマフォでブロックしたいように見えるのsem_waitではなく、使用してください。少なくとも部分が成功したかどうかを確認しsem_trywaitたい場合。sem_trywaittry

編集:修正されたソース。

#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 関数を使用している場合は、同期を確保するために、この呼び出しによって返される値を確認する必要があります...

詳細については、これを参照でき ます....

お役に立てれば...

于 2011-03-13T17:25:12.340 に答える