操作系统实验4-信号量的实现和应用

卡卡西至 https://blog.csdn.net/ccshijtgc/article/details/60327130

sem.c

#define __LIBRARY__  
#include <unistd.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <asm/segment.h>
#include <asm/system.h>

sem_t *sem_head = &((sem_t *){"\0",0,NULL,NULL});

sem_t *sys_sem_open(const char *name,int value){
        char pname[SEM_NAME_LEN];
        sem_t *sem_cur,*sem_pre;
        //获取用户态字符串
        char c;
        int i;

        for(i=0;(c=get_fs_byte(name++))!='\0' && i<SEM_NAME_LEN;i++)
                pname[i]=c;
        pname[i]='\0';
        //查看是否存在
        for(sem_pre=sem_head,sem_cur=sem_head->next ;sem_cur&&strcmp(pname,sem_cur->name);sem_pre=sem_cur,sem_cur=sem_cur->next)

        //新建一个
        if(!sem_cur){
                printk("semaphore %s no found. created a new one. \n", pname);
                sem_cur = (sem_t *)malloc(sizeof(sem_t));
                strcpy(sem_cur->name,pname);
                sem_cur->value = value;
                sem_cur->next =NULL;
                sem_pre->next = sem_cur;

        }
        printk("pid %d opens semaphore %s(value %u) OK. \n", current->pid, pname, sem_cur->value);
    return sem_cur;
}

int sys_sem_wait(sem_t *sem){
        //关中断
        cli();
        //<=0sLEEP
        while(sem->value<=1)
                sleep_on(&(sem->s_wait));
        //--
        sem->value--;
        //开中断
        sti();
        return 0;
}

int sys_sem_post(sem_t *sem){
        sem->value++;
        if(sem->value>0){
                wake_up(&(sem->s_wait));
                return 0;
        }
        return -1;
}

int sys_sem_unlink(const char *name){
         char pname[SEM_NAME_LEN];
        sem_t *sem_cur,*sem_pre;
        //获取用户态字符串
        char c;
        int i;

        for(i=0;(c=get_fs_byte(name++))!='\0' && i<SEM_NAME_LEN;i++)
                pname[i]=c;
        pname[i]='\0';
        //查看是否存在
        for(sem_pre=sem_head,sem_cur=sem_head->next ;sem_cur&&strcmp(pname,sem_cur->name);sem_pre=sem_cur,sem_cur=sem_cur->next)

        //不存在
        if(!sem_cur)
                return -1;

        //存在
        sem_pre->next = sem_cur->next;
        free(sem_cur);

        printk("unlink semaphore %s OK. \n", pname);
        return 0;


}

PC.C

#include <stdio.h>
#include <stdlib.h>
#define   __LIBRARY__
#include <unistd.h>


_syscall2(sem_t *,sem_open,const char *,name,int,value);
_syscall1(int,sem_wait,sem_t *,sem);
_syscall1(int,sem_post,sem_t *,sem);
_syscall1(int,sem_unlink,const char *,name);

#define CONSUMERS  5
#define PRODUCER 50
#define BUFFSIZE 10  

int item_pro,item_used;
sem_t *empty,*full,*mutex;

int main(){
        int pid;
        int i;
        int fi;
        int fo;
        fi = open("buff.dat",O_CREAT|O_TRUNC|O_WRONLY,0222);
        fo = open("buff.dat",O_TRUNC|O_RDONLY,0444);
        mutex = sem_open("mutex",1);
        full = sem_open("full",0);
        empty = sem_open("empty",BUFFSIZE);


        if((pid=fork()))
        {
                printf("pid %d:\tproducer created....\n", pid);
                fflush(stdout);
                while(item_pro<=PRODUCER){
                        printf("debug1\n");
                        sem_wait(empty);
                        printf("debug2\n");
                        sem_wait(mutex);
                        printf("debug3\n");
                        if(!(item_pro % BUFFSIZE))
                        lseek(fi, 0, 0);

                        write(fi, (char *) &item_pro, sizeof(item_pro));        /* 写入产品编号 */
                        printf("pid %d:\tproduces item %d\n", pid, item_pro);
                        fflush(stdout);
                        item_pro++;
                        sem_post(mutex);
                        sem_post(full);
                }

        }else{
                i = CONSUMERS;
                while(i--){
                        if((pid=fork())==0){
                                pid = getpid();
                                printf("pid %d:\tconsumer %d created....\n", pid, CONSUMERS-i);
                                fflush(stdout);
                                while(1){
                                        sem_wait(full);
                                        sem_wait(mutex);
/*read()读到文件末尾时返回0,将文件的位置指针重新定位到文件首部 */
                                         if(!read(fo, (char *)&item_used, sizeof(item_used)))
                                        {
                                                lseek(fo, 0, 0);
                                                read(fo, (char *)&item_used, sizeof(item_used));
                                        }

                                        printf("pid %d:\tconsumer %d consumes item %d\n", pid, CONSUMERS-i+1, item_used);
                                        fflush(stdout);
                                        sem_post(mutex);
                                        sem_post(empty);
                                        if(item_used==PRODUCER)
                                                goto OK;


                                }

                        }

                }



        }

OK:
        sem_unlink("empty");
        sem_unlink("full");
        sem_unlink("mutex");
        close(fi);
        close(fo);
        return 0;



}

结果

在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值