您将如何完成此计划以及您将使用多少信号量来获取
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个正常))
答案 0 :(得分:1)
我认为你使用优先图的方法是正确的,但是
问题陈述有点不清楚,例如,从图中可以看出
看起来像B
和C
可以按任何顺序出现,但没有任何迹象
这在原始a)和b)序列中。
(编辑:很明显,B
和C
必须交替使用
因此,对于案例a)以下(无限) 序列是可以接受的:
ABCD ACBD ABCD ACBD ABCD ACBD ...
A<--+
/ \ |
B<->C |
\ / |
D---+
A
在程序逻辑之前B
,它们在同一个线程中。
同样,C
出于D
出于同样的原因。因此,只需沿着边A->C
,B->D
和D->A
强制执行优先顺序,就需要信号量。 B
和C
之间的边缘会在每个周期中改变方向,因此我们需要额外的状态位来确定方向:B->C
或B<-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):)