问题1:读者写者问题
层次1:只有读者,最多允许有k个读者,用p,v操作写出程序。
int main() { int rspace = k; cobegin read_1(); read_2(); …… read_n(); coend } read_i() { p(rspace); …… v(rspace); }
这个操作,需要设置信号灯rspace来控制是否达到了k个人数,当达到k个人数的时候rspace == 0,这个时候需要挂起。
层次2:一个读者,一个写者问题。
int main() { int mutex = 1; cobegin read_i(); write_i(); coend } read_i()//i = 1, 2, …… { p(mutex); …… v(mutex); } write()//i = 1, 2, …… { p(mutex); …… v(mutex); }
这是一个临界资源,对于临界资源,需要设置信号灯mutex控制只有一个进程可以访问。
层次3:有多名读者,有多名写者。
int main() { int mutex = 1;//这个是读和写的互斥 int mutex1 = 1;//这个是保护cnt等变量 cobegin read_i(); write_i(); coend } read_i()//i = 1, 2, …… { p(mutex1); cnt ++; if(cnt == 1) { p(mutex); } v(mutex1); …… p(mutex1); cnt --; if(cnt == 0) { v(mutex); } v(mutex1); } write()//i = 1, 2, …… { p(mutex); …… v(mutex); }
这个资源,mutex把读和写的互斥,用mutex1把cnt临界资源保护起来。//问题:那么mutex本身不需要保护吗?怎么保证不会同时去修改mutex的值?
层次4:有多名读者,至多k名读者,有多名写者。
int main() { int mutex = 1;//这个是读和写的互斥 int mutex1 = 1;//这个是保护cnt等变量 int cnt = 0; int rspace = k; cobegin read_i(); write_i(); coend } read_i()//i = 1, 2, …… { p(mutex1); p(rspace); cnt ++; if(cnt == 1) { p(mutex); } v(mutex1); …… p(mutex1); cnt --; if(cnt == 0) { v(mutex); } v(rspace); v(mutex1); } write()//i = 1, 2, …… { p(mutex); …… v(mutex); }
这个需要rspace = k这个来保证,也就是说当临界值的时候,就是rspace = 0 的时候就是临界值。
问题2:誊抄问题
问题由来:
由于打印机,和卡带机(以前的输入设备)的输入比较慢,如果一个输入一个输出速度比较慢,所以设立了两个缓冲区,可以讲时间缩短。
设原来时间:输入一个字符T1,打印一个字符T2,那么一个字符从输入到输出总共时间T1 + T2,优化后时间是max(T1 + T2);
//输入f,输出g int main() { get(s, t); while(誊抄未完) { t = s; cobegin get(s, f); put(t, g); coend } }
这个题目的关键在于:
1. 首先要get(s, t)保证一开始的时候s缓冲区中有需要被使用的内容,t缓冲区中的内容不被使用。
2. t = s是一个赋值操作,速度极快,忽略不计,因此时间取决于max(T1 + T2);
题目要求:
n理发店里有一位理发师、一把理发椅和n把供等候理发的顾客休息的椅子;如果没有顾客,理发师便在理发椅上睡觉,当有顾客到来时,他唤醒理发师;如果理发师正在理发时又有新的顾客来到,那么如果还有空椅子,顾客就坐下来等待,否则就离开理发店。
步骤一:
barber:如果有顾客就理发,没有顾客就不理发。临界条件是有没有顾客,因此定义顾客数cnt = 0;
custermer:如果有空位置就坐在空位置,如果没有空位置就走开,不存在等空位置的状态,因此只存在判断语句,没有临界值。
int main() { int cnt = 0;//顾客的个数 cobegin barber(); customer(); coend } barber() { while(1) { p(cnt); …… } } customer_i()//1,2,…… { if(cnt < n + 1) v(cnt); }
问题:这个时候的cnt是存在于customer 和 barber共同之中的,因此可能出现custermer 和 barber 共同改变 cnt的情况,所以说需要设置一个变量mutex保护cnt这个变量的互斥操作。
步骤二:
int main() { int cnt = 0;//顾客的个数 int mutex = 0; cobegin barber(); customer(); coend } barber() { while(1) { p(mutex); p(cnt); v(mutex); …… } } customer_i()//1,2,…… { p(mutex); if(cnt < n + 1) v(cnt); v(mutex); }
问题2:
/*对于每个custemer来说,整个程序应该是一个互相通信的过程,custermer -> barber -> custermer完成。理发完之后custermer才可以杀死进程,而不可以申请完立即杀死进程。所以存在一个等待barber 的通信变量。*/
对于这个问题,我们先看一下p操作和v操作的工作原理。
p(k)操作:如果 k > 1,那么就索要操作成功,如果k < 1,那么索要操作失败,同时把k的值减小1,把该进程挂在到k的wait队列中去。
v(k)操作:释放k所代表的一个资源,如果k < 0,(假设k = -m,那么m就代表等待队列中的进程个数)那么同时取出wait等待队列中的一个进程继续进行。
简而言之,p操作是申请资源,v操作是释放资源。
未完待续。