与信号量原语进行流程同步

时间:2011-11-23 15:54:49

标签: c synchronization operating-system semaphore

您将如何完成此计划以及您将使用多少信号量来获取

a)ABCD ACBD序列

b)ABCD ABDC序列

使用这两个过程(考虑使用伪代码:wait(s1)signal(s1)等...)

流程1

P1:while(1){
        .
        printf("A");
        .
        .
        printf("C");
        .
   }       

流程2

 P2:while(1){
        .
        printf("B");
        .
        .
        printf("D");
        .
   }

将点视为可插入缺失代码(基元)的位置

@Jerry

经过一些互联网研究后,我认为我的第一点(a)已经解决了,

解决方案是建立一个像这样的优先图

      A<--(s0)--^
     / \        |
(s1)-- --(s2)   |
(me)-------     |
    /   \       |
   B     C      |
    \   /       |
   -------(s3)  |
     \ /        |
      D-------->|

INIT(s0)= INIT(ME)= 1 和INIT(s1)= INIT(s2)= INIT(s3)= 0

因此我有P1

P1:while(1){
       wait(s0);
       printf("A");
       signal(s2);
       signal(s1);

       wait(s1);
       wait(ME);
       printf("C");
       signal(ME);
       signal(s3)
   }

和P2

P2:while(1){
       wait(s2);
       wait(ME);
       printf("B");
       signal(s3);
       signal(ME);

       wait(s3);
       wait(s3);
       printf("D");
       signal(s0)
   }

您认为我的方法是对的吗?,我可以减少使用的信号量吗? (现在有5个(2个互斥和3个正常))

1 个答案:

答案 0 :(得分:1)

我认为你使用优先图的方法是正确的,但是 问题陈述有点不清楚,例如,从图中可以看出 看起来像BC可以按任何顺序出现,但没有任何迹象 这在原始a)和b)序列中。

编辑:很明显,BC必须交替使用

因此,对于案例a)以下(无限) 序列是可以接受的:

ABCD ACBD ABCD ACBD ABCD ACBD ...

  A<--+
 / \  |
B<->C |
 \ /  |
  D---+

A在程序逻辑之前B,它们在同一个线程中。 同样,C出于D出于同样的原因。因此,只需沿着边A->CB->DD->A强制执行优先顺序,就需要信号量。 BC之间的边缘会在每个周期中改变方向,因此我们需要额外的状态位来确定方向:B->CB<-C可以使用额外的变量,或者我们可以通过复制循环体来隐式地维护状态,如下所示:

#include <semaphore.h>
#include <pthread.h>
#include <stdio.h>

#define NLOOPS 100000

sem_t s0, s1, s2, s3;

void *
process_A (void *unused)
{
  int n = NLOOPS;

  while (n--)
    {
      sem_wait (&s0);
      putchar ('A');
      sem_post (&s1);
      putchar ('B');
      sem_post (&s3);
      sem_post (&s2);

      sem_wait (&s0);
      putchar ('A');
      sem_post (&s1);
      sem_wait (&s3);
      putchar ('B');
      sem_post (&s2);
    }

  return 0;
}

void *
process_B (void *unused)
{
  int n = NLOOPS;

  while (n--)
    {
      sem_wait (&s1);
      sem_wait (&s3);
      putchar ('C');
      sem_wait (&s2);
      putchar ('D');
      sem_post (&s0);

      sem_wait (&s1);
      putchar ('C');
      sem_post (&s3);
      sem_wait (&s2);
      putchar ('D');
      sem_post (&s0);
    }

  return 0;
}


int
main ()
{
  pthread_t a, b;

  sem_init (&s0, 0, 1);
  sem_init (&s1, 0, 0);
  sem_init (&s2, 0, 0);
  sem_init (&s3, 0, 0);

  pthread_create (&a, 0, process_A, 0);
  pthread_create (&b, 0, process_B, 0);

  pthread_join (a, 0);
  pthread_join (b, 0);

  putchar ('\n');
  return 0;
}

我会让你自己实施b):)