【问题标题】:Process syncronization with semaphore primitives使用信号量原语进行进程同步
【发布时间】:2012-01-04 22:07:42
【问题描述】:

你将如何完成这个方案以及你将使用多少个信号量来获取

a) ABCD ACBD 序列

b) ABCD ABDC 序列

使用这两个进程(考虑使用伪代码es:wait(s1) signal(s1) etc...)

流程 1

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

流程 2

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

将点视为可以插入缺失代码(基元)的地方

@杰瑞

经过一些互联网研究,我想我的第一点 (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 个正常))

【问题讨论】:

  • 我认为通常的问题适用:到目前为止您尝试了什么以及遇到了什么问题?
  • 什么样的陈述应该放在点上?只有信号量操作或 ifs、打印等?
  • 我已经用我试图找到的解决方案编辑了这个问题,请检查一下,让我知道它是否正确以及我是否可以减少更多使用的信号量。

标签: c synchronization operating-system semaphore


【解决方案1】:

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

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

因此,对于情况 a) 以下(无限) 顺序是可以接受的:

ABCD ACBD ABCD ACBD ABCD ACBD ...

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

A 在程序逻辑上位于B 之前,它们在同一个线程中。 同样,出于同样的原因,C 位于 D 之前。因此,需要信号量来仅沿边缘A-&gt;CB-&gt;DD-&gt;A 强制执行优先级。 BC 之间的边在每个周期都会改变方向,因此我们需要一个额外的状态位来确定方向:B-&gt;CB&lt;-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) :)

【讨论】:

  • 不,B 和 C 的顺序是 EX-OR,它们交替出现,ABCD、ACBD、ABCD、ACBD 等等
  • 所以不是复制 putchar 语句而是使用互斥信号量的解决方案(?)
  • @LucianEnache,我看不出有办法通过额外的信号量来实现这一点。
猜你喜欢
  • 2015-04-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-31
  • 1970-01-01
相关资源
最近更新 更多