操作系统课堂练习5 && 课后练习5 (6题)

5-1-1多线程编程

一、答案

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

int sum1 = 0, sum2 = 0;

void *p1(){
	  int i, tmp = 0;
	  for (i = 1; i <= 100; i++)
	    	tmp += i;
	  sum1 += tmp;
}

void *p2(){
	  int i, tmp = 0;
	  for (i = 101; i <= 200; i++)
	    	tmp += i;
	  sum2 += tmp;
}

void p3(){
  	printf("sum: %d\n", sum1 + sum2);
}

int main(){
	  int res;
	  pthread_t t1, t2;
	  void *thread_result;
	  pthread_create(&t1, NULL, p1, NULL);
	  pthread_create(&t2, NULL, p2, NULL);
	  pthread_join(t1, NULL);
	  pthread_join(t2, NULL);
	  p3();
	  return 0;
}

二、需要注意的地方

①关于pthread_create和pthread_join函数调用

在这里插入图片描述
不需要有res、result等变量接收函数返回值,也不必要设置if语句处理线程创建失败等情况的处理语句(在不考虑代码健壮性的情况下)。
可以直接这样写

pthread_create(&t1, NULL, p1, NULL);
pthread_create(&t2, NULL, p2, NULL);
pthread_join(t1, NULL);
pthread_join(t2, NULL);

③关于2个线程和3个线程

2个线程不等于main函数中引用两次pthread_creat函数,而是pthread_creat函数创建的线程和原函数的线程加起来共有两个,三个线程同理。

5-1-2信号量的应用

一、答案

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

#define CUSTOMER_NUM  10

int customer_state[CUSTOMER_NUM] = {0};
/**********Here**********/
sem_t s;
/************************/
void sleep_random(int t) {
  sleep((int)(t * (rand() / (RAND_MAX *1.0))));
}

void print_cur_state() {
  int i;
  printf("  customers with seats: (");
  for (i = 0; i < CUSTOMER_NUM; i++)
  {
    if (0 != customer_state[i])
      printf(" %d", i+1);
  }
  printf(" )\n");
}

void *customer(void *id)
{
  const int myid = *(int*)id;
  sleep_random(2);
  printf("customer %d: try to get a seat...\n", myid);
  /**********Here**********/
  sem_wait(&s);
  /************************/
  printf("customer %d: sit down\n", myid);
  customer_state[myid-1] = 1;
  print_cur_state();
  sleep_random(3);
  /**********Here**********/
  sem_post(&s);
  /************************/
  printf("customer %d: stand up\n", myid);
  customer_state[myid-1] = 0;
  print_cur_state();
}

int main()
{
	  int i, id[CUSTOMER_NUM], res;
	  pthread_t t[CUSTOMER_NUM];
	  srand((int)time(0));
	  /**********Here**********/
	  sem_init(&s,0,2);
	  /*************************/
	  for (i = 0; i < CUSTOMER_NUM; i++)
	  {
		    id[i] = i + 1;
		    pthread_create(&t[i], NULL, customer, &id[i]);
	  }
	  for (i = 0; i < CUSTOMER_NUM; i++)
	  {
		    res = pthread_join(t[i], NULL);
		    if (res != 0)
		    {
		      	perror("failed to join thread");
		     	exit(2);
	  		}
	  }
	  return 0;
}

5-1-3

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

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

void delay(){
  int i = 10000000;
  while (i--)
    ;
}

#define N  5
sem_t chopstick[N];

void *phi(void *id){  /* 'id' starts from 1 */
  int i, left, right, myid = *(int*)id;
  left = myid - 1;
  right = (myid < N) ? myid : 0;
  for (i = 0; i < 3; i++){
    printf("phi #%d: start of thinking\n", myid);
/**** start *************/
	if(left > right )
	{
		int tmp = left; 
		left = right;
		right = tmp; 
	}
      sem_wait(&chopstick[left]);
      delay();
      sem_wait(&chopstick[right]);

/**** end ***************/
    printf("phi #%d: start of eating\n", myid);
    sleep_random(3);
    sem_post(&chopstick[left]);
    sem_post(&chopstick[right]);
    printf("phi #%d: end of eating\n", myid);
  }
}

int main(){
  int i, id[N];
  pthread_t t[N];
  srand((int)time(0));
  for (i = 0; i < N; i++){
    id[i] = i + 1;
    sem_init(&chopstick[i], 0, 1);
  }
  for (i = 0; i < N; i++)
    pthread_create(&t[i], NULL, phi, &id[i]);
  for (i = 0; i < N; i++)
    pthread_join(t[i], NULL);
  return 0;
}

5-2-1生产者与消费者问题

一、答案

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>
/**********Here**********/
#define N  8
/*************************/
#define PRODUCT_NUM 15
int buffer[N], readpos = 0, writepos = 0;
/**********Here**********/
sem_t full, empty, mutex, mutex1;
/*************************/
void sleep_random(int t) {
  sleep((int)(t * (rand() / (RAND_MAX *1.0))));
}

void *produce(void * id){
	  int i;
	  for (i = 0; i < PRODUCT_NUM; i++){
		    sleep_random(2);
		    
			sem_wait(&empty);
			/**********Here**********/
		  	sem_wait(&mutex);
		    int myid = *(int *)id * 1000 + i + 1;
		    buffer[writepos++] = myid;
		    /*************************/
		    if (writepos >= N)
		      		writepos = 0;
		    /**********Here**********/
		    printf("produce:    %d\n", myid );
		    sem_post(&mutex);
		    /*************************/
		    sem_post(&full);
	  }
}

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

int main(){
	/**********Here**********/
	 int res, i, id[6];
	 pthread_t pro[6];
	 pthread_t con[6];
	 /*************************/
	 for (i = 0; i < N; i++)
	   	buffer[i] =  - 1;
	 srand((int)time(0));
	 sem_init(&full, 0, 0);
	 sem_init(&empty, 0, N);
	 /**********Here**********/
	 sem_init(&mutex,0,1);
	 sem_init(&mutex1,0,1);
	 for(int i = 1; i <= 5; i++)
	 {
	   id[i] = i; 
	   pthread_create(&pro[i], NULL, produce, &id[i]);
	 }
	 for(int i = 1; i <= 5; i++)
		pthread_create(&con[i], NULL, consume, &id[i]);
	 for(int i = 1; i <= 5; i++)
	 {
		pthread_join(pro[i],NULL);
		pthread_join(con[i],NULL);
	 }
	 /*************************/
	 return 0;
}

二、需要注意的问题

①防止主线程过早结束

在主线程对每个子线程设置pthread_join,以防止主进程结束导致子进程在还未执行完前提前被杀死

②信号量数量错误

虽然produce与consum的互斥信号量共享一个输出的答案是对的,但是会导致评测显示信号量数量错误,consum与produce在设置互斥的时候,应该用不同的信号量。

③一串比较有意思的c语句

pthread_create(&pro[i], NULL, produce, &id[i]);
void *produce(void * id){
	...
	int myid = *(int *)id * 1000 + i + 1;
...
}

5-2-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
/************************************/
int buffer1[M], buffer2[N],readpos1 = 0, writepos1 = 0, readpos2 = 0, writepos2 = 0; 
sem_t full1, empty1, full2, empty2;/*mutex1. mutex2, mutex3;*/ 

/************************************/
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);
	buffer1[(writepos1++) % M] = i + 1;
	printf("P sends:    %d\n", i+1 );
	sem_post(&full1);

/************************************/
  }
}

void *Q(){
  int i, data;
  for (i = 0; i < LIMIT; i++){
    sleep_random(2);
/************************************/
  sem_wait(&full1);
  data = buffer1[(readpos1)%M];
  buffer1[(readpos1++) % M] = -1;
  
  sem_post(&empty1);
  sem_wait(&empty2);
  buffer2[(writepos2++) % N] = data;
  sem_post(&full2);
/************************************/
  }
}

void *R(){
	int i;
	for (i = 0; i < LIMIT; i++){
		sleep_random(2);
	/************************************/
	sem_wait(&full2);
	printf("R receives: %d\n", buffer2[(readpos2)%N]);
	buffer2[(readpos2++) % N] = -1;
	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(&full1,0,0);
	sem_init(&full2,0,0);
	sem_init(&empty1,0,M);
	sem_init(&empty2,0,N);
	/************************************/
	pthread_create(&t1, NULL, P, NULL);
	pthread_create(&t2, NULL, Q, NULL);
	R();
	pthread_join(t1,NULL);
	pthread_join(t2,NULL);
 
  return 0;
}

5-2-3理发师问题

#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

/**************Code HERE******************/
sem_t full1, empty1, full2, empty2;
/****************************************/

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

void *barber()
{
	while(5)
	{
		/**************Code HERE******************/
		sem_wait(&full2);
		/****************************************/
		printf("barber: start cutting\n");
		sleep_random(3);
		printf("barber: finish cutting\n");
		/**************Code HERE******************/
		sem_post(&empty2);
		/****************************************/
	}
}

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

	/**************Code HERE******************/
	sem_wait(&empty1);
	/****************************************/
	
	printf("customer %d: sit down\n", myid);
	 
	/**************Code HERE******************/
	sem_post(&full1);

	sem_wait(&empty2);
	sem_wait(&full1);
	/****************************************/
	printf("customer %d: enter cutting-room and sit down\n", myid);
	/**************Code HERE******************/
	sem_post(&empty1);
	sem_post(&full2);
	
	sem_wait(&empty2);
	/****************************************/
	printf("customer %d: bye\n", myid);
	/**************Code HERE******************/
	sem_post(&empty2);
	/****************************************/
}

int main()
{
	int i, id[CUSTOMER_NUM];
	pthread_t t[CUSTOMER_NUM];
	
	srand((int)time(0));
	/****************************************/
	  sem_init(&full1, 0, 0);
	  sem_init(&empty1, 0, 2);
	  sem_init(&full2, 0, 0);
	  sem_init(&empty2, 0, 1);
	/****************************************/
	
	for (i = 0; i < CUSTOMER_NUM; i++)
	{
		 id[i] = i + 1;
		 pthread_create(&t[i], NULL, customer, &id[i]);
	}
	barber();
	for (i = 0; i < CUSTOMER_NUM; i++)
		pthread_join(t[i], NULL);
	return 0;
}
???

在这里插入图片描述

 #include<stdio.h>
 #include<semaphore.h>

semaphore  A = 0, B = 0, C = 0, D = 0, E= 0, F = 0,mutex = 1;

void task(char letter)
{
/*处理任务A*/
	if(letter == 'A') 
    {
    	A();
    	V(A);
    }
/*处理任务B、C、E*/
	P(A)
    if(letter == 'B')
    {
    	B();
        V(B)
    }
    else if(letter == 'C')
    {
    	C();
        V(C)
    }
    	
	else if(letter == 'E')
    {
    	E();
        V(E)
    }
	V(A)
/*处理任务D*/
    P(mutex);
    P(B);
    P(C);
    V(mutex);
		if(letter == 'D'{
        	D();
        	V(D);
        }
    P(mutex);
    V(B);
   V(C); 
   V(mutex);
   /*处理任务F*/
    P(mutex);
    P(E);
    P(D);
    V(mutex);
    	if(letter == 'F'{
       	F();
       	V(F);
       }
    P(mutex);
    V(E);
   V(D); 
   V(mutex);
   /*处理任务G、H*/
    P(F);
    	if(letter == 'G'G();
       if(letter == 'H')
       	H();
	V(F)
}
广州大学操作系统课后的习zyl主要涉及操作系统的基本概念、功能和特征。学习这些习可以帮助我们更好地理解操作系统的工作原理和应用场景。 首先,操作系统是计算机系统中的核心软件,它负责管理和控制计算机硬件资源,并为用户和应用程序提供服务。习zyl中可能会涉及到操作系统的功能,如进程管理、内存管理、文件系统管理等。我们需要学习各个管理模块的基本概念和功能。 其次,操作系统有着不同的特征和分类。习zyl可能会要求我们了解操作系统的特征,如并发性、共享性、虚拟性、异步性等。我们需要对这些特征有深入的理解,并能够应用到具体的操作系统场景中。 此外,习可能还会要求我们掌握操作系统的基本概念和术语,如进程、线程、调度算法、页表等。这些概念是操作系统的基础,也是我们理解和使用操作系统的前提。 为了更好地完成习zyl,我们可以采取以下学习方法:首先,认真听讲课堂上的操作系统知识,掌握基本概念和原理。其次,多做一些操作系统实验和编程练习,提高对操作系统的实际应用能力。最后,多和同学、老师或者在线讨论区交流,共同解决习中的难。 通过认真学习和应用,我们将能够更好地掌握操作系统的基本知识和技能,为我们的学业和职业发展打下坚实的基础。同时,操作系统作为计算机科学的重要基础学科,对我们理解计算机原理和技术具有重要作用。因此,我们应该积极投入到操作系统的学习中,提高对操作系统的理解和应用水平。
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值