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

1.首先复习了下,关于信号量的基本知识,我知道的借口基本有三套了,但是主要的都是解决PV操作,P为:等待,如果信号量不为0,即减1,如果为0的话,即进入等待,V:唤醒P操作等待的线程或者是进程,下面是实验中使用的接口:

//初始化
sem_t *sem_open(const char *name, unsigned int value);
//P操作
int sem_wait(sem_t *sem);
//V操作
int sem_post(sem_t *sem);
//释放
int sem_unlink(const char *name);

2)下面是自己写的生产者和消费者测试代码,注意在编译的时候,需要链接:-lpthread

#include <stdio.h>
#include <stdlib.h>
#include <semaphore.h>
#include <sys/sem.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
//联系模型生产者和消费者模型
//实现一个进程负责生产,N个进程负责消费
#define BUFFER_SIZE 10
sem_t* empty;
sem_t* full;
sem_t* mutex;

int main(void)
{
    int fd_file = open("pc.log",O_CREAT|O_RDWR,0644);    
    empty = sem_open("empty",O_CREAT,0644,10);
    full  = sem_open("full",O_CREAT,0644,0);
    mutex = sem_open("mutex",O_CREAT,0644,1); //可以进行生产
    //将文件大小设置为0
    ftruncate(fd_file,0);
    //如果有这些信号量的话,先释放
    sem_unlink("empty");
    sem_unlink("full");
    sem_unlink("mutex");
    if(!fork())
    {
    //child  producer
        int i = 0;
    while(i < 500)
        {
        i++;
        sem_wait(empty);
        sem_wait(mutex);
            // write the data to file
        lseek(fd_file,0,SEEK_END);
        write(fd_file,&i,sizeof(i));
            sem_post(mutex);
        sem_post(full);
    }
       while(1);
    }
    if(!fork())
    {
    int result = 0;
    int tmpResult = 0;
    int fileLen = 0;
        int j = 0;
    //consumer
    while(1)
    {
        sem_wait(full);
        sem_wait(mutex);
        //读取数据,同时将数据删除,从头开始读
            lseek(fd_file,0,SEEK_SET);
        read(fd_file,&result,sizeof(result));
        printf("%ld:%d\n",getpid(),result);
        // delete data from file
        fileLen = lseek(fd_file,0,SEEK_END);
        for(j = 1; j < fileLen/sizeof(result);j++)
        {
        lseek(fd_file,j*sizeof(result),SEEK_SET);   
        read(fd_file,&tmpResult,sizeof(tmpResult));
        lseek(fd_file,(j - 1)*sizeof(result),SEEK_SET);
            write(fd_file,&tmpResult,sizeof(tmpResult));
        }
        ftruncate(fd_file,fileLen - sizeof(result));
        sleep(1);
        sem_post(mutex);
        sem_post(empty);
        }
    }
    if(!fork())
    {
        int result = 0;
    int tmpResult = 0;
    int fileLen = 0;
        int j = 0;
    while(1)
    {
       //consumer
        sem_wait(full);
        sem_wait(mutex);
        //读取数据,同时将数据删除,从头开始读
            lseek(fd_file,0,SEEK_SET);
        read(fd_file,&result,sizeof(result));
        printf("%ld:%d\n",getpid(),result);
        // delete data from file
        fileLen = lseek(fd_file,0,SEEK_END);
        for(j = 1; j < fileLen/sizeof(result);j++)
        {
        lseek(fd_file,j*sizeof(result),SEEK_SET);   
        read(fd_file,&tmpResult,sizeof(tmpResult));
        lseek(fd_file,(j - 1)*sizeof(result),SEEK_SET);
            write(fd_file,&tmpResult,sizeof(tmpResult));
        }
        ftruncate(fd_file,fileLen - sizeof(result));
        sleep(1);
        sem_post(mutex);
        sem_post(empty);
        }
    }
    wait(NULL);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值