操作系统实验四:多线程与信号量编程

操作系统实验上机

更多技术请访问:www.xuanworld.top

部分审核不通过的文章将发至个人博客:www.xuanworld.top

欢迎来52破解论坛阅读帖子:https://www.52pojie.cn/thread-1891208-1-1.html

实验名称实验序号实验日期实验人
多线程与信号量编程4公元2077年Rytter

一、实验题目

20240525143602

二、相关原理和知识

  1. linux有关于信号量的相关函数,可以直接调用
  2. 利用pthread进行创建进程,每个进程都会有一个id
  3. 创建进程后每个进程都会对buffer进行互斥操作

三、实验过程

  1. 编写关于信号量与进程id的函数
  2. 编写对buffer进行操作的两个函数
  3. 编写消费者与生产者的函数
  4. 编写创建生产者与消费者的函数
  5. 放到Linux服务器上进行编译和运行

四、实验结果

20240525143717

五、问题总结

  1. 编译时出现问题,原因位命令行没有使用pthread
  2. 消费者的printf代码位置不对,导致还没消费就产生输出

六、源码

首先是buffer.h文件

typedef int buffer_item;
#define BUFFER_SIZE 5

之后是main.c文件

#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
#include <stdlib.h>
#include <unistd.h>
#include "buffer.h"
buffer_item buffer[BUFFER_SIZE];
pthread_mutex_t mutex;
sem_t  full,empty;
void buffer_out(){
    int i;
    for ( i = 0; i <BUFFER_SIZE ; ++i) {
        printf("%d",buffer[i]);
    }
    printf("\n");
}
int insert_item(int a,int b){
    sem_wait(&empty);
    pthread_mutex_lock(&mutex);
    int i;
    for(i = 0;i < BUFFER_SIZE;i++){
        if(buffer[i] == 0){
            buffer[i] = 1;//找到空的位置
            break;
        }
    }

    if(i == BUFFER_SIZE) return -1;
    printf("producer %d produced %d\n",a,b);
    buffer_out();
    pthread_mutex_unlock(&mutex);
    sem_post(&full);
    return 0;
}
int remove_item(int a,int b){
    sem_wait(&full);
    pthread_mutex_lock(&mutex);
    int i;
    for(i = 0;i < BUFFER_SIZE;i++){
        if(buffer[i] != 0){
            buffer[i] = 0;
            break;
        }
    }
    if(i == BUFFER_SIZE) return -1;
    printf("consumer %d consumed %d\n",a,b);//第几个吃了几个食物
    buffer_out();
    pthread_mutex_unlock(&mutex);
    sem_post(&empty);
    return 0;
}

void * producer(void * param){
    int* num = (int*)param;
    int food_id=0;
    while(1){
        sleep(((rand() % 10) + 1));
        if(insert_item(*num,++food_id))
            printf("wrong\n");
    }
}

void * consumer(void *param){
    int* num = (int*)param;
    int food_id=0;
    while(1){
        sleep(((rand() % 10) + 1));

        if(remove_item(*num,++food_id))
            printf("wrong\n");
    }
}

int main(int argc,char *argv[])
{
    //1.获取命令行输入的数字
    if(argc != 4) return -1;
    int sleep_time = atoi(argv[1]);
    int producer_num = atoi(argv[2]);
    int consumer_num = atoi(argv[3]);
    //2.进行初始化
    pthread_mutex_init(&mutex,NULL);
    sem_init(&empty,0,BUFFER_SIZE);
    sem_init(&full,0,0);
    int i;
    for(i=0;i<BUFFER_SIZE;i++) buffer[i]=0;
    //3.创建线程
    pthread_t producer_tid[producer_num];
    int producer_id[producer_num];
    for(i = 0;i < producer_num;i++){
        producer_id[i] = i + 1;
        pthread_create(&producer_tid[i],NULL,producer,&producer_id[i]);
    }
    pthread_t consumer_tid[consumer_num];
    int consumer_id[consumer_num];
    for(i = 0;i < consumer_num;i++){
        consumer_id[i] = i + 1;
        pthread_create(&consumer_tid[i],NULL,consumer,&consumer_id[i]);
    }
    //4.休眠
    sleep(sleep_time);
    //5.退出
    return 0;
}
  • 6
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值