0


课后作业5:进程的同步与互斥

第一关:生产者与消费者问题

信号量是4个,除了题目里已经给出的2个之外,还有分别针对生产者和消费者的mutex。

切记要把四个信号量在同一行中定义!

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>

#define N  8
#define PRODUCT_NUM 15
int buffer[N], readpos = 0, writepos = 0;
sem_t full, empty, mutexC, mutexP; //添加生产者和消费者的mutex
void sleep_random(int t) {
  sleep((int)(t * (rand() / (RAND_MAX *1.0))));
}
#define PRODUCER_CNT 5
#define CONSUMER_CNT 5
void *produce(void *idx){
    int id =*((int*)idx); //创建线程的id
    int i;
    for (i = 0; i < PRODUCT_NUM; i++){
        sleep_random(2);
        sem_wait(&empty);
        sem_wait(&mutexP); 
        sem_wait(&mutexC);
        buffer[writepos++] = 1000*(id) + i + 1;
        if (writepos >= N)
            writepos = 0;
        printf("produce:    %d\n", 1000*(id) + i + 1);
        sem_post(&mutexC);
        sem_post(&mutexP);
        sem_post(&full);
    }
}

void *consume(){
    int i;
    for (i = 0; i < PRODUCT_NUM; i++){
        sleep_random(2);
        sem_wait(&full);
        sem_wait(&mutexP);
        printf("consume: %d\n", buffer[readpos]);
        buffer[readpos++] =  - 1;
        if (readpos >= N)
            readpos = 0;
        sem_post(&mutexP);
        sem_post(&empty);
    }
}

int main(){
    int res, i;
    pthread_t t1[PRODUCER_CNT],t2[CONSUMER_CNT];
    for (i = 0; i < N; i++)
        buffer[i] =  - 1;
    srand((int)time(0));
    sem_init(&full, 0, 0);
    sem_init(&empty, 0, N);
    sem_init(&mutexP, 0, 1);
    sem_init(&mutexC, 0, 1);
    for (i = 0; i < PRODUCER_CNT; i++)
        res = pthread_create(&t1[i], NULL, produce, &i);
    if (res != 0){
        perror("failed to create thread");
        exit(1);
    }
    for (i = 0; i < CONSUMER_CNT; i++)
        res = pthread_create(&t2[i], NULL, consume, NULL);
    if (res != 0){
        perror("failed to create thread");
        exit(1);
    }
    void* resj;
    for(i = 0; i < PRODUCER_CNT; i++){
        pthread_join(t1[i],&resj);
    }
    for(i = 0; i < CONSUMER_CNT; i++){
        pthread_join(t2[i],&resj); 
    }
    return 0;
}

第二关:三个并发进程

  1. 不要看到长空格就写\t,要换成8个空格才能通过(以下代码使用了\t)

  2. 注意几个信号量的请求顺序

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>

#define LIMIT  20
#define M  5
#define N  8
/************************************/
sem_t mtp,mtq,mtr,full1,empty1,empty2,full2;
int buffer1[M],buffer2[N];
/************************************/
void sleep_random(int t) {
  sleep((int)(t * (rand() / (RAND_MAX *1.0))));
}

void *P(){
  int i;
  for (i = 0; i < LIMIT; i++){
    sleep_random(2);
/************************************/
    sem_wait(&empty1);
    sem_wait(&mtq);
    sem_wait(&mtp);
    buffer1[i%M]=i+1;
    printf("P sends:\t%d\n",i+1);
    sem_post(&mtp);
    sem_post(&mtq);
    sem_post(&full1);
/************************************/
  }
}

void *Q(){
  int i, data;
  for (i = 0; i < LIMIT; i++){
    sleep_random(2);
/************************************/
    int t;
    sem_wait(&full1);
    sem_wait(&mtp);
    sem_wait(&mtq);
    t=buffer1[i%M];
    sem_post(&mtq);
    sem_post(&mtp);
    sem_post(&empty1);

    sem_wait(&empty2);
    sem_wait(&mtr);
    sem_wait(&mtq);
    buffer2[i%N]=t;
    sem_post(&mtq);
    sem_post(&mtr);
    sem_post(&full2);
/************************************/
  }
}

void *R(){
  int i;
  for (i = 0; i < LIMIT; i++){
    sleep_random(2);
/************************************/
    sem_wait(&full2);
    sem_wait(&mtq);
    sem_wait(&mtr);
    printf("R receives: %d\n",buffer2[i%N]);
    sem_post(&mtr);
    sem_post(&mtq);
    sem_post(&empty2);
/************************************/
  }
}

int main(){
  int i;
  pthread_t t1, t2;
  for (i = 0; i < M; i++)
    buffer1[i] =  - 1;
  for (i = 0; i < N; i++)
    buffer2[i] =  - 1;
  srand((int)time(0));
/************************************/
  sem_init(&mtp,0,1);
  sem_init(&mtq,0,1);
  sem_init(&mtr,0,1);
  sem_init(&full1,0,0);
  sem_init(&empty1,0,M);
  sem_init(&full2,0,0);
  sem_init(&empty2,0,N);
/************************************/
  pthread_create(&t1, NULL, P, NULL);
  pthread_create(&t2, NULL, Q, NULL);
  R();
  return 0;
}

第三关:理发师问题

可以理解为缓存容量分别为2,1,1的第二题。信号量的排序需要注意。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>

#define SEAT_NUM  2
#define CUSTOMER_NUM  5

/************************************/
sem_t empty,full,empty2,full2,mtb,mtw;//mutex lock for the barber and waiting room
int buffer[SEAT_NUM], cur_serv, readpos = 0, writepos = 0;//waiting room
/************************************/

void sleep_random(int t) {
  sleep((int)(t * (rand() / (RAND_MAX *1.0))));
}

void *barber()
{
  while(5)
  {
/************************************/
    sem_wait(&full);
    buffer[readpos++] = -1;
    if (readpos >= SEAT_NUM){
        readpos = 0;
    }
    sem_post(&empty);
    sem_wait(&empty2);
/************************************/
    printf("barber: start cutting\n");
    sleep_random(3);
    printf("barber: finish cutting\n");
/************************************/
    sem_post(&full2);
/************************************/
  }
}

void *customer(void *id)
{
  const int myid = *(int*)id;
  sleep_random(2);
  printf("customer %d: enter waiting-room\n", myid);

/************************************/
  sem_wait(&empty);
  sem_wait(&mtw);
/************************************/
  printf("customer %d: sit down\n", myid);

/************************************/
  buffer[writepos++] = myid;
  if (writepos >= SEAT_NUM)
      writepos = 0;
  sem_post(&mtw);
  sem_wait(&mtb);
/************************************/
  printf("customer %d: enter cutting-room and sit down\n", myid);
/************************************/
  cur_serv = myid;
  sem_post(&full);
  sem_wait(&full2);
/************************************/
  printf("customer %d: bye\n", myid);
/************************************/
  sem_post(&mtb);
  sem_post(&empty2);
/************************************/
}

int main()
{
  int i, id[CUSTOMER_NUM];
  pthread_t t[CUSTOMER_NUM];

  srand((int)time(0));
/************************************/
  sem_init(&empty,0,SEAT_NUM);
  sem_init(&full,0,0);
  sem_init(&full2,0,0);
  sem_init(&empty2,0,1);
  sem_init(&mtb,0,1);
  sem_init(&mtw,0,1);
/************************************/

  for (i = 0; i < CUSTOMER_NUM; i++)
  {
    id[i] = i + 1;
    pthread_create(&t[i], NULL, customer, &id[i]);
  }
  barber();
  return 0;
}
标签: c++ c语言 linux

本文转载自: https://blog.csdn.net/qq_33965473/article/details/128117312
版权归原作者 tzzzzzzzx 所有, 如有侵权,请联系我们删除。

“课后作业5:进程的同步与互斥”的评论:

还没有评论