微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

c – “信号量的使用是错误的”

在过去的一个学期,我正在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);
}

解决方法

你的信号量在最内圈没有任何保护缓冲区,头等等.一个线程获取sempahore“空”,另一个获取信号量“满”,而没有其他信号量被保持.这似乎保证最终的腐败.

原文地址:https://www.jb51.cc/c/112917.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐