进程同步与互斥实验

进程同步与互斥实验

#include
#include
#include
#include
#define true 1
//生产者ID
int product_id = 0;
//消费者ID
int consumer_id = 0;
//缓冲区大小
int N;
//生产者数目
int producerNum;
//消费者数目
int consumerNum;
//类型定义 int型 信号
typedef int semaphore;
//类型定义 int型 商品
typedef int item;
//定义 商品类型的缓冲数组
item* buffer;
//头索引,输入索引,头指针,用于标识生产者的输入位置
int in = 0;
//尾索引,输出索引,尾指针,用于标识消费者的输出位置
int out = 0;
//产品数目
int proCount = 0;
//mutex 互斥变量,empty 缓冲区空白大小,full 缓冲区非空白大小,proCmutex 生产者互斥变量
semaphore mutex = 1, empty , full = 0, proCmutex = 1;
//pthread_create函数创建进程时,需要一个指针类型的函数作为参数,所以定义为指针类型。
//producer与consumer作为线程的执行体。
void * producer(void * a){
int id = ++product_id;
while(true){
int flag = 0;
//如果缓冲区已满报错
while(empty <= 0){
printf(“生产者%d:缓冲区已满!阻塞中……\n”,id);
flag =1;
sleep(1);
}
if(flag ==1)
printf(“生产者%d因缓冲区有空位唤醒!\n”,id);
//如果有其他生产者占用进程则互斥,检查有没有其他生产者生产产品
flag = 0;
while(proCmutex <= 0){printf(“生产者%d生产阻塞中……\n”,id);flag = 1;sleep(1);};
//将互斥变量置0,代表已占用
proCmutex–;
if(flag == 1)
printf(“生产者%d生产唤醒!\n”,id);
//产品号+1
proCount++;
printf(“生产者%d:生产一个产品ID%d!\n”,id,proCount);

    //总互斥变量,检查有没有其他进程修改缓冲区数据
    flag = 0;
    while(mutex <= 0){printf("生产者%d装入阻塞中……\n",id);sleep(1);flag=1;};
    //占用进程
    mutex--;

    if(flag == 1)
        printf("生产者%d装入唤醒,装入产品ID%d,缓冲区位置为%d!\n",id,proCount,in);
    else
        printf("生产者%d装入产品ID%d,缓冲区位置为%d!\n",id,proCount,in);
    //否则缓冲区空白大小-1
    empty--;
    //缓冲区头指针放入产品
    buffer[in] = proCount;
    //头指针+1
    in = (in + 1) % N;

    //缓冲区非空白大小+1
    full++;
    //解除占用
    mutex++;
    //解除生产占用
    proCmutex++;
    //睡一觉
    sleep(1);
}

}

void * consumer(void *b){
int id = ++consumer_id;
while(true){
int flag = 0;
while(full <= 0){
printf("\t\t\t\t消费者%d:缓冲区为空!阻塞中……\n",id);
flag = 1;
sleep(1);
}
full–;
if(flag ==1)
printf("\t\t\t\t消费者%d因缓冲区有产品唤醒!\n",id);
flag = 0;

    while(mutex <= 0){printf("\t\t\t\t消费者%d消费阻塞中……\n",id);sleep(1);};
    mutex--;
    if(flag == 1)
        printf("\t\t\t\t消费者%d消费唤醒!\n",id);
    int nextc = buffer[out];
    buffer[out] = 0;//消费完将缓冲区设置为0
    empty++;
    printf("\t\t\t\t消费者%d:消费一个产品ID%d,缓冲区位置为%d\n",id, nextc,out);
    out = (out + 1) % N;
    mutex++;
    sleep(1);
}

}

int main()
{
int tempnum;
//输入生产者数目
printf(“请输入生产者数目:\n”);
scanf("%d",&tempnum);
producerNum = tempnum;
//输入消费者数目
printf(“请输入消费者数目:\n”);
scanf("%d",&tempnum);
consumerNum = tempnum;
//输入缓冲区大小
printf(“请输入缓冲区大小:\n”);
scanf("%d",&tempnum);
N = tempnum;
empty = N;
buffer = (item*)malloc(N*sizeof(item));
for(int i=0;i {
buffer[i]=0;
}
//pthread_t是线程结构,用来保存线程相关数据,可以理解为线程类型,声明线程对象(这里声明的时线程对象数组)
pthread_t threadPool[producerNum+consumerNum];//声明了线程数组作为线程池
int i;
for(i = 0; i < producerNum; i++){
pthread_t temp;
//if语句中,第一个参数是线程指针,第二个是线程属性指针,第三个是函数指针,即线程要执行的代码
//函数通过producer函数指针创建对象,赋值给temp作为线程执行
if(pthread_create(&temp, NULL, producer, NULL) == -1)
{
printf(“ERROR, fail to create producer%d\n”, i);
exit(1);
}
//将temp作为能够执行的线程放入了进程池
threadPool[i] = temp;
}//创建生产者进程放入线程池

//对于消费者进程也同样创建进程
for(i = 0; i < consumerNum; i++){
    pthread_t temp;
    if(pthread_create(&temp, NULL, consumer, NULL) == -1){
        printf("ERROR, fail to create consumer%d\n", i);
        exit(1);
    }
    threadPool[i+producerNum] = temp;
}//创建消费者进程放入线程池


void * result;
for(i = 0; i < producerNum+consumerNum; i++){
    //pthread_join函数用与等待线程的结束
    //等待的是子进程的结束,因为如果主进程不等待子进程而直接结束,子进程将没有执行就被杀死。
    if(pthread_join(threadPool[i], &result) == -1){
        printf("fail to recollect\n");
        exit(1);
    }
}//运行线程池
return 0;

}

远哥是真强啊!帅!

你可能感兴趣的:(科技)