上个学期我在C中学习了OS实习,其中第一个项目涉及制作一个线程包,然后编写一个多生产者 - 消费者程序来演示功能。然而,在获得评分反馈之后,我失去了“信号量的使用是巧妙的错误”和“程序假设抢占(例如使用产量来改变控制)”(我们从一个非抢占式线程包开始然后稍后添加抢占)。请注意,注释和示例相互矛盾。我相信它也不会假设,并且可以在两种环境中工作。)
这已经困扰了我很长一段时间 - 课程工作人员有点不知所措,所以我不能问他们这个学期有什么问题。我花了很长时间思考这个,我看不出问题。如果有人可以看一看并指出错误,或者向我保证实际上没有问题,我真的很感激。
我认为语法在线程包函数(minithreads和semaphores)方面应该是非常标准的,但是如果有什么问题让我知道。
#include <stdio.h>
#include <stdlib.h>
#include "minithread.h"
#include "synch.h"
#define BUFFER_SIZE 16
#define MAXCOUNT 100
int buffer[BUFFER_SIZE];
int size, head, tail;
int count = 1;
int out = 0;
int toadd = 0;
int toremove = 0;
semaphore_t empty;
semaphore_t full;
semaphore_t count_lock; // Semaphore to keep a lock on the
// global variables for maintaining the counts
/* Method to handle the working of a student
* The ID of a student is the corresponding minithread_id */
int student(int total_burgers) {
int n, i;
semaphore_P(count_lock);
while ((out+toremove) < arg) {
n = genintrand(BUFFER_SIZE);
n = (n <= total_burgers - (out + toremove)) ? n : total_burgers - (out + toremove);
printf("Student %d wants to get %d burgers ...\n", minithread_id(), n);
toremove += n;
semaphore_V(count_lock);
for (i=0; i<n; i++) {
semaphore_P(empty);
out = buffer[tail];
printf("Student %d is taking burger %d.\n", minithread_id(), out);
tail = (tail + 1) % BUFFER_SIZE;
size--;
toremove--;
semaphore_V(full);
}
semaphore_P(count_lock);
}
semaphore_V(count_lock);
printf("Student %d is done.\n", minithread_id());
return 0;
}
/* Method to handle the working of a cook
* The ID of a cook is the corresponding minithread_id */
int cook(int total_burgers) {
int n, i;
printf("Creating Cook %d\n",minithread_id());
semaphore_P(count_lock);
while ((count+toadd) <= arg) {
n = genintrand(BUFFER_SIZE);
n = (n <= total_burgers - (count + toadd) + 1) ? n : total_burgers - (count + toadd) + 1;
printf("Cook %d wants to put %d burgers into the burger stack ...\n", minithread_id(),n);
toadd += n;
semaphore_V(count_lock);
for (i=0; i<n; i++) {
semaphore_P(full);
printf("Cook %d is putting burger %d into the burger stack.\n", minithread_id(), count);
buffer[head] = count++;
head = (head + 1) % BUFFER_SIZE;
size++;
toadd--;
semaphore_V(empty);
}
semaphore_P(count_lock);
}
semaphore_V(count_lock);
printf("Cook %d is done.\n", minithread_id());
return 0;
}
/* Method to create our multiple producers and consumers
* and start their respective threads by fork */
void starter(int* c){
int i;
for (i=0;i<c[2];i++){
minithread_fork(cook, c[0]);
}
for (i=0;i<c[1];i++){
minithread_fork(student, c[0]);
}
}
/* The arguments are passed as command line parameters
* argv[1] is the no of students
* argv[2] is the no of cooks */
void main(int argc, char *argv[]) {
int pass_args[3];
pass_args[0] = MAXCOUNT;
pass_args[1] = atoi(argv[1]);
pass_args[2] = atoi(argv[2]);
size = head = tail = 0;
empty = semaphore_create();
semaphore_initialize(empty, 0);
full = semaphore_create();
semaphore_initialize(full, BUFFER_SIZE);
count_lock = semaphore_create();
semaphore_initialize(count_lock, 1);
minithread_system_initialize(starter, pass_args);
}
答案 0 :(得分:5)
您的信号量无法保护最内层循环中的缓冲区,磁头等。一个线程获得sempahore“empty”,另一个获取信号量“full”而没有其他信号量被保持。这似乎可以保证最终的腐败。