@H_301_1@在过去的一个学期,我正在C中进行操作系统实践,其中第一个项目涉及制作线程包,然后编写多个生产者 – 消费者程序来演示功能.然而,在获得分级反馈后,我失去了“使用信号量是微妙的错误”和“程序假设抢占(例如使用收益来改变控制)”的点(我们以非抢占式线程包开始,然后再添加抢占.请注意,评论和示例相互矛盾,我相信它不会假设,也可以在两种环境中工作.
这已经很麻烦了我很长一段时间 – 课程的工作人员很沮丧,所以我不能问他们这个学期在这个问题上有什么问题.我花了很长时间思考这个问题,我看不到问题.如果有人可以看看并指出错误,或者放心我确实没有问题,我真的很感激.
我相信语法应该在线程包函数(微线程和信号量)方面非常标准,但是让我知道是否有任何疑惑.
#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",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",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",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); }